公司经常遇到发送邮件的问题,普通邮件发送就不说了,说一下无账号密码发送邮件的过程,在这里总结一下:
邮件收发协议:发送邮件使用smtp协议,收取邮件使用pop或imap协议;这里我们只讲发送邮件的smtp协议;
这部分说明是从网上摘抄的,写的很详细,我就贴过来修改了一下:
使用smtp协议发送邮件给邮件服务器时规定了要做以下几件事:
1、使用"ehlo"命令和连接上的smtp服务器打声招呼,例如:
ehlo zqz
命令格式为 “ehlo 当前计算机的hostname”; zqz即为当前计算机的主机名;
2、使用"auth login"命令登录到Smtp服务器,登录使用的用户名和密码必须经过Base64加密,例如:
①、输入命令:auth login
②、输入使用Base64加密过后的用户名:Z2FjbA==
③、输入Base64加密过后的密码:MTIzNDU2
说明:好多企业内部邮箱不需要设置用户名密码,一般都是将发送邮件的服务器ip列入白名单,那么这一步就可以省略;
3、指明邮件的发件人和收件人
mail from:
rcpt to:
4、编写要发送的邮件内容,邮件的编写格式是有一定的规则的,一封格式良好的邮件应该包含邮件头和邮件的主体内容。
邮件头使用下面的三个字段来指明:
邮件的内容包含了这些信息之后才是一封格式良好的邮件。
①、输入"data"命令
data
②、编写邮件内容
Cc:[email protected] ----邮件头 抄送给谁
From:[email protected] ----邮件头 邮件发送者
To:[email protected] ----邮件头 邮件接收者
Subject:hello test ----邮件头 邮件标题
----空行
hello test ----邮件的具体内容
5、输入一个.告诉邮件服务器邮件内容已经写完了。
.
6、输入quit命令断开与邮件服务器的连接。
quit
以上的6个步骤就是Smtp协议规定的发送一封Email必须要做的事情。
下面就用命令行来执行一下整个过程:
[C:\Users\Administrator]$ telnet smtp.tingyun.com 25
Host 'smtp.tingyun.com' resolved to 163.177.72.143.
Connecting to 163.177.72.143:25...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
220 smtp.qq.com Esmtp QQ Mail Server //连接成功后服务器主动推送的消息,220为响应代码,后面欢迎消息说明服务器的域名为smtp.qq.com ,协议为Esmtp ,服务器名为QQ Mail Server;
ehlo localhost //此命令成功后,服务器推送支持的认证方式
250-smtp.qq.com
250-PIPELINING
250-SIZE 73400320
250-STARTTLS
250-AUTH LOGIN PLAIN //这里是服务器返回的支持的验证方式 LOGIN 和PLAIN两种方式
250-AUTH=LOGIN
250-MAILCOMPRESS
250 8BITMIME
auth login //此命令向服务器发起认证请求
334 VXNlcm5hbWU6 //334代表等待输入命令 后面字符串代表输入用户名 ,解码后就是Username:
ZXRwdGVzdEB0aW5neXVuLmNvbQ== //base64的用户名
334 UGFzc3dvcmQ6 //334代表等待输入命令 后面字符串代表输入密码,解码之后就是Password:
VFl1bjAxMA== //base64的密码
235 Authentication successful //235代表验证通过,如果验证失败则返回530
mail from:
250 Ok
rcpt to:<[email protected]> //谁接收邮件
250 Ok
data //data命令代表邮件正文
354 End data with
From:[email protected] //发送者
To:[email protected] //接收者
Cc:[email protected] //抄送
Subject:hello test //标题
Content-Type: text/plain
//回车空行 ,此行上面是head,下面是body
hello test. //邮件正文
. // .代表正文结束
250 Ok: queued as
以上红色部分为我们自己需要输入的命令行。
qq邮箱收到的邮件:
hello test |
|
发件人:etptest |
时 间:2018年5月9日(星期三) 下午5:36 | 纯文本 | |
收件人: randolpha <[email protected]> 抄 送: zhuqz |
|
hello test.
HELO是普通SMTP,不带身份验证,可以伪造邮件!一般如果不关闭SMTP的话,就可以制造垃圾邮件了,这个已经没有公司使这种方式了;
EHLO是ESMTP,带有身份验证,所以没法伪造。
SMTP协议发送邮件使用的是com.sun.mail.smtp.SMTPTransport这个类,建立连接,验证身份的逻辑在protocolConnect方法里面;
如果不设置mail.smtp.auth 和 mail.smtp.ehlo ,默认mail.smtp.auth = false,mail.smtp.ehlo=true;
相关的代码逻辑在com.sun.mail.smtp.SMTPTransport.protocolConnect()的613行:
// setting mail.smtp.ehlo to false disables attempts to use EHLO
boolean useEhlo = PropUtil.getBooleanSessionProperty(session, "mail." + name + ".ehlo", true);
// setting mail.smtp.auth to true enables attempts to use AUTH
boolean useAuth = PropUtil.getBooleanSessionProperty(session, "mail." + name + ".auth", false);
判断是否需要执行auth login操作验证用户名和密码在第682行:
if ((useAuth || (user != null && passwd != null)) &&
(supportsExtension("AUTH") ||
supportsExtension("AUTH=LOGIN"))) {
connected = authenticate(user, passwd);
注意这里的判断条件 ,如果mail.smtp.auth = true 或者 用户名和密码都不为null;
也就是在以下条件都会进程login验证:
1. mail.smtp.auth = true ;
2. mail.smtp.auth = false, 但是用户名和密码都不为null;
所以如果我们不去设置mail.smtp.auth参数(那么它默认就是false),只要将用户名和密码设置为null或者非null,即可让java决定是否需要执行login操作;所以建议不要设置mail.smtp.auth参数,只使用用户名和密码来控制是否执行login操作;
注意:
1. 对于不需要用户名和密码发送邮件的情况,需要将mail.smtp.auth = false或不设置(默认就是fasle),并把userName和password设置为null;
2. 对于exchange邮箱发送邮件,userName不要设置加@邮箱域名后面的内容,只需要@符号前的用户名即可;
500 格式错误,命令不可识别(此错误也包括命令行过长)
501 参数格式错误
502 命令不可实现
503 错误的命令序列
504 命令参数不可实现
211 系统状态或系统帮助响应
214 帮助信息
220
221
421
250 要求的邮件操作完成
251 用户非本地,将转发向
450 要求的邮件操作未完成,邮箱不可用(例如,邮箱忙)
550 要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问)
451 放弃要求的操作;处理过程中出错
551 用户非本地,请尝试
452 系统存储不足,要求的操作未执行
552 过量的存储分配,要求的操作未执行
553 邮箱名不可用,要求的操作未执行(例如邮箱格式错误)
354 开始邮件输入,以
554 操作失败
如果要使用SSL发送邮件:
mail.smtp.starttls.enable=true; mail.smtp.ssl.protocols=TLSv1.2;
mail.smtp.starttls.enable的说明:
If true, enables the use of the STARTTLS command (if supported by the server) to switch the connection to a TLS-protected connection before issuing any login commands. Note that an appropriate trust store must configured so that the client will trust the server's certificate. Defaults to false.
如果设置为true, 则在执行登陆命令前,会使用STRRTTLS命令选择使用TLS方式建连(前提是邮件服务器必须支持TLS方式)。
需要注意的是,在我们的客户端,必须将服务器端的证书配置到我们的信任列表里面(信任列表就是truststore,用来存放信任的证书的,不清楚是什么的需要去度娘一下);
默认值为false;
下面是阿里云禁用25端口的情况下如何使用465端口smtps协议发送邮件
https://www.unixhot.com/article/303