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
相关产品推荐
相关产品推荐

