VB.NET通过System.Net.Mail的SMTP发送365邮件突然失效求助
问题排查优先级(按匹配症状的概率从高到低排序)
1. 最高概率:Microsoft 365 已强制禁用对应租户/账号的SMTP基本身份验证
微软从2023年开始分批对所有Microsoft 365租户推送默认配置,直接关闭SMTP服务的基本身份验证能力,不需要租户管理员手动操作,推送完成后所有用账号密码直连smtp.office365.com:587的老代码会在认证阶段被服务端直接拒绝,邮件根本不会进入365的发信队列,所以发件箱、已发送文件夹看不到记录,也不会产生退信。
目前完全看不到报错的核心原因是代码里用了SendAsync却没有注册异常回调,所有连接、认证阶段抛出的错误都被静默吞掉了。
- 快速验证方法:把
SendAsync临时换成同步方法Send(),外层套try-catch块本地运行,90%以上概率会抓到类似5.7.139 Authentication unsuccessful, SmtpClientAuthentication is disabled for the Tenant的明确报错。 - 临时修复方案:
- 登录Microsoft 365管理中心,先确认租户层级未全局禁用SMTP AUTH,再进入对应发信账号的邮箱设置页,在「邮件应用」配置里勾选「经过身份验证的SMTP」权限。
- 如果租户开启了安全默认值/强制MFA策略,需要给这个发信账号生成专用的应用密码替换代码里的原账号密码,否则即使开了SMTP AUTH也会认证失败。
- 长期建议:弃用老旧的
System.Net.Mail.SmtpClient,改用官方推荐的Microsoft Graph API对接365发信,后续不会再受SMTP协议相关的策略调整影响。
2. 次高概率:TLS版本不匹配
Microsoft 365已完全弃用TLS 1.0、TLS 1.1协议的连接请求,仅接受TLS 1.2及以上版本的加密连接。如果应用基于.NET Framework 4.5及更早版本开发,运行时默认使用的TLS版本低于1.2,会在SSL握手阶段被服务端直接断开连接,同样不会产生任何邮件记录。
- 验证方法:在初始化SmtpClient之前添加如下代码,再测试发信:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
3. 其他待排查项
- 补全代码的异常捕获逻辑:不要在生产环境使用无回调的
SendAsync方法,要么注册SendCompleted事件捕获异步发送的错误,要么改用同步发送加完整try-catch,把错误信息落日志,避免后续出问题完全无排查线索。 - 检查Azure AD登录日志:如果上述两项都没解决,去365后台的Azure AD登录日志里筛选对应账号的SMTP登录记录,能看到明确的失败原因,常见的包括条件访问策略拦截、账号权限变更、密码过期(即使网页端能登,也可能存在缓存登录导致没发现密码已过期的情况)。
' 临时排查用的带错误捕获的测试代码示例 Private Sub TestSendEmail() Try ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Dim MS365Email As New MailMessage MS365Email.To.Add("RECIPIENTEMAIL") MS365Email.From = New MailAddress("SENDEREMAIL") MS365Email.Subject = "TEST SUBJECT" MS365Email.IsBodyHtml = True MS365Email.Body = "TEST BODY" Dim MS365client As New SmtpClient("smtp.office365.com", 587) MS365Email.Priority = MailPriority.Normal MS365client.EnableSsl = True MS365client.UseDefaultCredentials = False MS365client.Credentials = New Net.NetworkCredential("USERNAME", "APPPASSWORD") MS365client.DeliveryMethod = SmtpDeliveryMethod.Network ' 临时用同步方法抓错 MS365client.Send(MS365Email) MessageBox.Show("发送成功") Catch ex As Exception ' 输出ex的完整错误信息即可直接定位根因 MessageBox.Show($"发送失败:{ex.ToString()}") End Try End Sub
内容的提问来源于stack exchange,提问作者JPC
相关产品推荐
相关产品推荐

