最近做系统内审批业务,需要发送邮件,在本地使用公司邮箱测试时,是没有问题的,没有使用发件服务器验证;
项目使用的是spring boot 2.x;
初始配置文件:
spring:
mail:
host: smtp.xx.com
port: 25
username: wang_xxx@xxx.com
password: xxxx
这里host是邮箱服务器地址;
password按理说应该是授权码,但这里直接用的是邮箱登录密码,本地测试邮件是发送成功的;
后来在用户测试环境,使用用户 提供的测试邮箱相关配置,发送邮件时,提示的是:
错误1:
Authentication failed; nested exception is javax.mail.AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful;
后来知道用户提供的这个邮箱,只能在他们内网登录,且发送邮件时,是有身份验证的;
于是修改配置,继续尝试:
mail:
host: smtp.xxx.com.cn
port: 25
username: xxx@xxx.com.cn
password: ccccc
properties:
mail:
debug: true
smtp:
ssl:
trust: smtp.xxx.com.cn
enable: true
auth: true
auth.mechanisms: NTLM
starttls:
enable: true
required: true
上述配置报错是:
错误2:
Mail server connection failed; nested exception is javax.mail.MessagingException: Could not connect to SMTP host: smtp.gtmc.com.cn, port: 25;
nested exception is:
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?. Failed messages: javax.mail.MessagingException: Could not connect to SMTP host: smtp.gtmc.com.cn, port: 25;
nested exception is:
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
--------------------------------------------------------------------------------------------------------------------------
后续又修改了配置,又有新的报错信息:
错误3:
Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS;
nested exception is:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS;
nested exception is:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
=====================================================
这里我想说一句,由于用户提供的信息有限,只知道有发件服务器验证,我们需要去多次的尝试,试错;
但是很多时候,我们是不知道,现在的错误到底是不是正确的错误;
我这里是尝试了很多次,也看了网上很多相关解决方案;
----------------------------------
针对错误1的解决方案:
错误1的提示,其实就是:身份验证失败;
那么针对这个问题,我初始的解决方法,是添加配置,配置2:
mail:
mail.debug: true
smtp:
ssl:
trust: smtp.xxx.com.cn
enable: true
auth: true
auth.mechanisms: NTLM
starttls:
enable: true
required: true
但是加了这些之后,得到的报错信息是错误2的信息;
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?;
于是又尝试修改配置,配置3:
mail:
debug: true
smtp:
auth: true
auth.mechanisms: NTLM
starttls:
enable: true
required: true
这次的报错信息是错误3;
后来在配置2的基础上,
看到有文章说,ssl.enable和starttls.enable不能同时存在;
于是继续修改配置;
properties:
mail:
debug: true
smtp:
ssl:
trust: smtp.xxx.com.cn
auth: true
auth.mechanisms: NTLM
starttls:
enable: true
required: true
这里有开启debug格式,所以能看到cmd窗口打印的debug日志;
下图是日志截图:
如果你开启debug能看到这些信息,说明你距离成功不远了;
这让我看到了希望,能让我觉得,这个错误是正确的错误,于是顺着这个继续修改配置;
接着,在上面的配置基础上,添加了配置:
auth.ntlm.domain: smtp.xxx.com.cn
如下是完整配置:
mail:
host: smtp.xxx.com.cn
port: 25
username: xxxxx
password: xxxxx
properties:
mail:
debug: true
smtp:
ssl:
trust: smtp.xxx.com.cn
auth: true
auth.mechanisms: NTLM
auth.ntlm.domain: smtp.xxx.com.cn
starttls:
enable: true
required: true
这里要注意一下:
需要注意的是username是登陆邮箱是的用户名而不是邮箱,password是登陆邮箱的密码,mail.smtp.auth.ntlm.domain是邮箱服务器的domain。
根据上面的配置,再执行发送邮件,cmd窗口报错信息:
注意看,这里我们已经是认证成功了,报错信息是无效的地址,这是由于我发件时,发件人的邮箱是使用邮件配置里的username,所以设置一下邮箱地址就可以了;
可以根据用户名去判断,给定邮箱地址,然后再次尝试;
邮件发送成功;
结语:
编程这一行业,其实很多时候就是在不断的试错,当我们错的足够多了,就意味着我们距离正确更近;
但是,也不要一条路走到黑,有时候,换个思维,改变一下想法,或许也会有不一样的结果呢!