Exchange Online Basic身份验证弃用对C# Office365 SMTP实现的影响及迁移建议咨询
Office 365 SMTP 邮件发送代码迁移至现代认证(Modern Authentication)指南
先理清Basic与Modern认证的核心区别
- Basic 身份验证:将用户名和密码做Base64编码后传输(本质等同于明文),安全风险高,微软已逐步在Exchange Online中弃用该方式。
- Modern 身份验证:基于OAuth 2.0协议,支持多因素认证(MFA)、短期令牌过期机制,安全性更强,是微软官方推荐的认证方案。
迁移步骤与代码实现
前提准备
- 在Azure AD中注册一个应用程序,获取以下信息:
- 租户ID(Tenant ID)
- 客户端ID(Client ID)
- 客户端密钥(Client Secret,或使用证书更安全)
- 给该应用分配SMTP.Send应用权限(注意是应用权限,而非委派权限,适合后台服务无用户交互的场景)
- 由租户管理员对该权限授予管理员同意
1. 安装依赖包
优先使用MailKit(对SMTP和OAuth支持更完善,且System.Net.Mail在.NET 5+已标记为过时),安装以下NuGet包:
Install-Package MailKit Install-Package Microsoft.Identity.Client
2. MailKit + OAuth 2.0 代码示例
using MailKit.Net.Smtp; using MailKit.Security; using Microsoft.Identity.Client; using MimeKit; public async Task SendEmailWithModernAuth() { // 替换为你的实际配置 var tenantId = "your-tenant-id"; var clientId = "your-client-id"; var clientSecret = "your-client-secret"; var smtpServer = "smtp.office365.com"; var smtpPort = 587; var senderEmail = "sender@yourdomain.com"; var recipientEmail = "recipient@example.com"; // 构建邮件 var message = new MimeMessage(); message.From.Add(new MailboxAddress("发件人", senderEmail)); message.To.Add(new MailboxAddress("收件人", recipientEmail)); message.Subject = "Modern Auth 测试邮件"; message.Body = new TextPart("plain") { Text = "这是通过现代认证发送的测试邮件内容" }; // 获取OAuth 2.0令牌 var scopes = new[] { "https://outlook.office365.com/.default" }; var app = ConfidentialClientApplicationBuilder .Create(clientId) .WithClientSecret(clientSecret) .WithTenantId(tenantId) .Build(); var authResult = await app.AcquireTokenForClient(scopes).ExecuteAsync(); // 发送邮件 using (var client = new SmtpClient()) { await client.ConnectAsync(smtpServer, smtpPort, SecureSocketOptions.StartTls); // 使用OAuth 2.0认证 await client.AuthenticateAsync(new SaslMechanismOAuth2(senderEmail, authResult.AccessToken)); await client.SendAsync(message); await client.DisconnectAsync(true); } }
3. 兼容System.Net.Mail的方案(不推荐)
如果暂时无法切换到MailKit,可参考以下代码(仅适合.NET框架或早期.NET版本):
using System.Net; using System.Net.Mail; using Microsoft.Identity.Client; public async Task SendEmailWithSystemNetMail() { var tenantId = "your-tenant-id"; var clientId = "your-client-id"; var clientSecret = "your-client-secret"; var smtpServer = "smtp.office365.com"; var smtpPort = 587; var senderEmail = "sender@yourdomain.com"; var recipientEmail = "recipient@example.com"; // 获取令牌 var scopes = new[] { "https://outlook.office365.com/.default" }; var app = ConfidentialClientApplicationBuilder .Create(clientId) .WithClientSecret(clientSecret) .WithTenantId(tenantId) .Build(); var authResult = await app.AcquireTokenForClient(scopes).ExecuteAsync(); // 发送邮件 var mailMessage = new MailMessage(senderEmail, recipientEmail) { Subject = "Modern Auth 测试邮件", Body = "通过System.Net.Mail发送的现代认证测试邮件" }; using (var smtpClient = new SmtpClient(smtpServer, smtpPort)) { smtpClient.EnableSsl = true; smtpClient.UseDefaultCredentials = false; // 用OAuth令牌作为密码 smtpClient.Credentials = new NetworkCredential(senderEmail, authResult.AccessToken); await smtpClient.SendMailAsync(mailMessage); } }
关键注意事项
- 权限验证:务必确认Azure AD应用的
SMTP.Send权限已获得管理员同意,否则会出现认证失败错误。 - 令牌管理:OAuth令牌默认有效期约1小时,建议每次发送邮件前获取新令牌,或实现令牌缓存逻辑避免重复请求。
- MFA支持:应用权限模式下无需用户交互,天然兼容启用MFA的发件人账户。
- 库的选择:MailKit是更现代、可靠的邮件处理库,建议优先迁移到该库,避免依赖已过时的
System.Net.Mail。
内容的提问来源于stack exchange,提问作者Muhammedh
相关产品推荐
相关产品推荐

