请求验证含Nonce的Azure AD登录JWT令牌并用于C# API认证
验证带Nonce的Azure AD JWT令牌(C# API实现)
首先明确:带Nonce字段的JWT完全可以验证,Nonce是Azure AD用来防范重放攻击的字段,并非验证障碍,只需确保请求传入的Nonce与令牌Header中的Nonce值一致即可。
一、用官方库快速实现基础认证
借助Microsoft Identity Web库,它会自动处理令牌的签名、有效期、受众等核心验证逻辑,只需在Program.cs中配置:
using Microsoft.Identity.Web; var builder = WebApplication.CreateBuilder(args); // 接入Azure AD认证服务 builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration); var app = builder.Build(); // 启用认证与授权中间件 app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
对应的appsettings.json需配置你的Azure AD信息:
{ "AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "你的租户域名", "TenantId": "你的租户ID", "ClientId": "你的API应用ClientID", "Audience": "你的API受众标识" } }
二、手动添加Nonce验证逻辑
官方库默认不会自动校验Access Token(你当前使用的是Microsoft Graph的Access Token)中的Nonce,因此需要自定义验证逻辑,比如编写一个授权过滤器:
using System.IdentityModel.Tokens.Jwt; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.Filters; public class ValidateNonceFilter : IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { // 从请求头获取前端传递的Nonce(需前端将登录时生成的Nonce存入该请求头,示例为X-Nonce) if (!context.HttpContext.Request.Headers.TryGetValue("X-Nonce", out var requestNonce)) { context.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedResult(); return; } // 解析令牌中的Nonce字段 var authHeader = context.HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", ""); var tokenHandler = new JwtSecurityTokenHandler(); if (!tokenHandler.CanReadToken(authHeader)) { context.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedResult(); return; } var jwtToken = tokenHandler.ReadJwtToken(authHeader); jwtToken.Header.TryGetValue("nonce", out var tokenNonceObj); var tokenNonce = tokenNonceObj?.ToString(); // 比对请求Nonce与令牌Nonce if (tokenNonce != requestNonce) { context.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedResult(); } } }
在需要验证的控制器上应用该过滤器:
[Authorize] [ServiceFilter(typeof(ValidateNonceFilter))] [ApiController] [Route("api/[controller]")] public class BusinessController : ControllerBase { [HttpGet] public IActionResult GetData() { return Ok("认证通过,数据返回"); } }
三、关键注意事项
- 前端必须将登录时生成的Nonce值,在请求API时通过请求头或参数传递,否则无法完成Nonce比对验证。
- 若使用的是ID Token而非Access Token,官方库会自动校验Nonce,无需手动编写逻辑。
内容的提问来源于stack exchange,提问作者Satit Porntepanon
相关产品推荐
相关产品推荐

