You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Exchange Online Basic身份验证弃用对C# Office365 SMTP实现的影响及迁移建议咨询

Office 365 SMTP 邮件发送代码迁移至现代认证(Modern Authentication)指南

先理清Basic与Modern认证的核心区别

  • Basic 身份验证:将用户名和密码做Base64编码后传输(本质等同于明文),安全风险高,微软已逐步在Exchange Online中弃用该方式。
  • Modern 身份验证:基于OAuth 2.0协议,支持多因素认证(MFA)、短期令牌过期机制,安全性更强,是微软官方推荐的认证方案。

迁移步骤与代码实现

前提准备

  1. 在Azure AD中注册一个应用程序,获取以下信息:
    • 租户ID(Tenant ID)
    • 客户端ID(Client ID)
    • 客户端密钥(Client Secret,或使用证书更安全)
  2. 给该应用分配SMTP.Send应用权限(注意是应用权限,而非委派权限,适合后台服务无用户交互的场景)
  3. 由租户管理员对该权限授予管理员同意

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:50:44