.NET Core 6 API中基于Azure AD实现双认证方案求助
解决方案:.NET Core 6 API实现Azure AD内部用户认证(适配双认证流程)
一、Azure AD配置与后端服务注册
首先在appsettings.json中添加Azure AD相关配置:
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "你的租户域名", "TenantId": "你的租户ID", "ClientId": "API应用注册的ClientId", "ClientSecret": "API应用注册的ClientSecret", "CallbackPath": "/api/auth/internal/callback" }
然后在Program.cs中注册Azure AD认证服务:
using Microsoft.AspNetCore.Authentication.AzureAD.UI; using Microsoft.Identity.Web; using Microsoft.IdentityModel.Tokens; using System.Text; var builder = WebApplication.CreateBuilder(args); // 注册Azure AD认证方案 builder.Services.AddAuthentication() .AddAzureAD(options => builder.Configuration.Bind("AzureAd", options)); // 配置JWT验证(用于保护后续API接口) builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) }; }); builder.Services.AddControllers(); builder.Services.AddHttpClient(); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
二、内部认证API实现(含回调处理)
创建InternalAuthController,处理前端认证请求和Azure AD回调逻辑:
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.AzureAD.UI; using Microsoft.AspNetCore.Mvc; using System.IdentityModel.Tokens.Jwt; using System.Net.Http; using System.Threading.Tasks; [Route("api/auth/internal")] [ApiController] [AllowAnonymous] public class InternalAuthController : ControllerBase { private readonly IConfiguration _configuration; private readonly IHttpClientFactory _httpClientFactory; public InternalAuthController(IConfiguration configuration, IHttpClientFactory httpClientFactory) { _configuration = configuration; _httpClientFactory = httpClientFactory; } // 前端触发内部认证的入口 [HttpGet("login")] public IActionResult InitiateAzureAdLogin() { var authProps = new AuthenticationProperties { RedirectUri = _configuration["AzureAd:CallbackPath"], Items = { { "scheme", AzureADDefaults.AuthenticationScheme } } }; // 引导用户到Azure AD登录页 return Challenge(authProps, AzureADDefaults.AuthenticationScheme); } // Azure AD认证完成后的回调处理 [HttpGet("callback")] public async Task<IActionResult> AzureAdCallback() { // 获取Azure AD认证结果 var authResult = await HttpContext.AuthenticateAsync(AzureADDefaults.AuthenticationScheme); if (!authResult.Succeeded) { return BadRequest("Azure AD认证失败"); } // 解析ID令牌,提取用户核心信息 var idToken = authResult.Properties.GetTokenValue("id_token"); var jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(idToken); var userEmail = jwtToken.Claims.FirstOrDefault(c => c.Type == "email")?.Value; var userRoles = jwtToken.Claims.Where(c => c.Type == "roles").Select(c => c.Value).ToList(); // 调用已实现的令牌生成API,生成自定义JWT var client = _httpClientFactory.CreateClient(); var tokenReq = new { Email = userEmail, Roles = userRoles, UserType = "Internal" }; var response = await client.PostAsJsonAsync($"{_configuration["ApiBaseUrl"]}/api/token/generate", tokenReq); if (!response.IsSuccessStatusCode) { return BadRequest("生成自定义令牌失败"); } var customToken = await response.Content.ReadFromJsonAsync<TokenResponse>(); // 返回自定义JWT给前端 return Ok(new { AccessToken = customToken.AccessToken, ExpiresIn = customToken.ExpiresIn }); } } // 令牌生成API的响应模型 public class TokenResponse { public string AccessToken { get; set; } public int ExpiresIn { get; set; } }
三、关键注意事项
- Azure AD应用配置:在Azure门户注册API应用时,需启用ID令牌,确保回调路径与配置的
CallbackPath完全一致;同时要为内部用户分配对应角色,保证角色声明能被包含在ID令牌中。 - 前端适配:前端请求
/api/auth/internal/login后,会跳转至Azure AD登录页,认证完成后自动回调到API,前端接收返回的自定义JWT后存入本地存储,后续请求携带该令牌访问受保护接口。 - 令牌生成API复用:内部、外部认证共用同一令牌生成API,仅通过
UserType参数区分用户类型,API统一生成包含角色、邮箱的标准JWT即可。
内容的提问来源于stack exchange,提问作者Gee
相关产品推荐
相关产品推荐

