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

C#/.NET应用跳转微软登录页、登录后捕获Token实现OAuth发邮件

.NET 集成微软OAuth2实现邮件发送完整方案

前置准备:Azure AD应用注册

  • 登录Azure门户,进入「Azure Active Directory」-「应用注册」,点击「新注册」
  • 填写应用名称,选择支持的账户类型(企业场景选择「仅此组织目录中的账户」即可)
  • 重定向URI填写你应用的回调地址:Web应用可填https://your-domain.com/signin-oidc,桌面/控制台应用可填https://login.microsoftonline.com/common/oauth2/nativeclient
  • 注册完成后记录「客户端ID」、「租户ID」,在「证书和密码」板块创建客户端密码并保存备用
  • 进入「API权限」板块,添加「Microsoft Graph」的委托权限:SMTP.Send、openid、email、profile,完成后点击「授予管理员同意」

步骤1:实现跳转微软登录页

以下以ASP.NET Core Web应用为例,首先安装所需NuGet包:
Microsoft.AspNetCore.Authentication.OpenIdConnect、Microsoft.Identity.Web、MailKit

配置认证服务(Program.cs)

var builder = WebApplication.CreateBuilder(args);

// 注入微软身份认证服务
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(options =>
    {
        builder.Configuration.Bind("AzureAd", options);
        options.Scope.Add("SMTP.Send");
        options.SaveTokens = true; // 自动保存返回的access token、id token等信息
    });

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

配置应用参数(appsettings.json)

"AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "TenantId": "你之前记录的租户ID",
  "ClientId": "你之前记录的客户端ID",
  "ClientSecret": "你之前记录的客户端密码",
  "CallbackPath": "/signin-oidc"
}

触发登录跳转

需要登录时直接返回Challenge结果,框架会自动重定向到微软登录页:

[HttpGet]
public IActionResult TriggerSendMail()
{
    // 未登录状态自动跳转微软登录页,登录完成后跳转到实际发邮件的接口
    if (!User.Identity.IsAuthenticated)
        return Challenge(new AuthenticationProperties { RedirectUri = Url.Action("ProcessSendMail") });
    return RedirectToAction("ProcessSendMail");
}

步骤2:登录成功后捕获Token、提取用户邮箱

登录完成后可直接从认证上下文获取Token和用户信息:

[HttpGet]
public async Task<IActionResult> ProcessSendMail()
{
    // 获取返回的Access Token
    var accessToken = await HttpContext.GetTokenAsync(OpenIdConnectDefaults.AuthenticationScheme, "access_token");
    // 从用户Claims中提取邮箱地址
    var userEmail = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email || c.Type == "preferred_username")?.Value;
    
    if (string.IsNullOrEmpty(accessToken) || string.IsNullOrEmpty(userEmail))
        return BadRequest("获取用户认证信息失败");
    
    // 调用发邮件逻辑
    await SendMailByOAuth2(userEmail, accessToken);
    return Ok("邮件发送成功");
}

步骤3:通过OAuth2认证发送邮件(基于MailKit)

private async Task SendMailByOAuth2(string senderEmail, string accessToken)
{
    // 构建邮件内容
    var mail = new MimeMessage();
    mail.From.Add(new MailboxAddress("发件人显示名", senderEmail));
    mail.To.Add(new MailboxAddress("收件人显示名", "recipient@example.com"));
    mail.Subject = "OAuth2认证测试邮件";
    
    mail.Body = new TextPart("plain")
    {
        Text = "这是通过微软OAuth2认证发送的测试邮件内容"
    };

    // 连接SMTP服务器并认证发送
    using var smtpClient = new SmtpClient();
    await smtpClient.ConnectAsync("smtp.office365.com", 587, SecureSocketOptions.StartTls);
    var oauthCredential = new SaslMechanismOAuth2(senderEmail, accessToken);
    await smtpClient.AuthenticateAsync(oauthCredential);
    await smtpClient.SendAsync(mail);
    await smtpClient.DisconnectAsync(true);
}

控制台/桌面应用适配方案

如果是客户端应用,可使用设备码流实现认证,安装NuGet包Microsoft.Identity.Client,示例代码如下:

var clientId = "你的客户端ID";
var tenantId = "你的租户ID";
var scopes = new[] { "SMTP.Send", "openid", "email", "profile" };

var publicClient = PublicClientApplicationBuilder
    .Create(clientId)
    .WithAuthority(AzureCloudInstance.AzurePublic, tenantId)
    .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
    .Build();

AuthenticationResult authResult;
try
{
    // 优先静默获取已缓存的Token
    authResult = await publicClient.AcquireTokenSilent(scopes, publicClient.Accounts.FirstOrDefault()).ExecuteAsync();
}
catch (MsalUiRequiredException)
{
    // 静默获取失败,触发设备码登录引导
    authResult = await publicClient.AcquireTokenWithDeviceCode(scopes, deviceCodeInfo =>
    {
        Console.WriteLine(deviceCodeInfo.Message);
        return Task.CompletedTask;
    }).ExecuteAsync();
}

var userEmail = authResult.Account.Username;
var accessToken = authResult.AccessToken;
// 后续直接调用上述SendMailByOAuth2方法即可

内容的提问来源于stack exchange,提问作者Sunil M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:24:03