.NET Core中JWT令牌声明如何填充至User.Claims
.NET JWT认证场景下HttpContext.User.Claims填充机制说明
问题背景
该问题源于项目代码执行流程排查需求,相关代码与核心疑问如下:
认证服务注册代码
public override void ConfigureServices(IServiceCollection services) { services.AddAuthentication() .AddJwtBearer() .AddCookie("Cookie"); }
自定义授权过滤器实现
服务规则要求所有REST API调用方必须在Authorization请求头中携带有效的AccessToken,项目实现了专属授权过滤器校验接口访问所需的声明:
namespace Authorization { public class ClaimRequirementFilter : IAuthorizationFilter { private readonly Claim _claim; public ClaimRequirementFilter(Claim claim) { _claim = claim; } public void OnAuthorization(AuthorizationFilterContext context) { var hasClaim = context.HttpContext.User.Claims.Any(c => string.Equals(c.Type, _claim.Type, StringComparison.OrdinalIgnoreCase) && string.Equals(c.Value, _claim.Value, StringComparison.OrdinalIgnoreCase)); if (!hasClaim) { context.Result = new UnauthorizedResult(); } } } }
过滤器使用方式
[HttpGet] [ActionName("GetUsers")] [ClaimRequirement("api_access", "users.read")] public async Task<IActionResult> GetUsers() { return Ok("Great success!"); }
核心疑问
HttpContext.User.Claims是通过何种机制从JWT令牌中提取并填充声明数据的?
完整执行流程说明
整个填充流程由ASP.NET Core认证管道自动完成,不需要业务代码手动解析JWT,核心执行步骤如下:
- 认证中间件前置执行:请求管道中
AuthenticationMiddleware的注册顺序在MVC中间件、自定义授权过滤器之前,会在业务逻辑执行前率先完成身份认证流程。调用AddJwtBearer()扩展方法时,框架会自动将JWT认证处理器注册到认证方案集合中,API请求场景下默认由该处理器负责身份校验。 - JWT令牌提取:JwtBearer处理器运行后,默认从请求头的
Authorization: Bearer <token>字段提取JWT字符串,未修改配置的情况下不会读取Cookie或其他位置存储的令牌。 - JWT合法性校验:拿到令牌后,处理器会按照预设规则完成校验:解码JWT的头部、载荷、签名三部分,使用配置的签名密钥验证签名未被篡改,同时校验令牌过期时间、签发者、受众等参数是否符合要求,校验不通过会直接返回401响应终止请求。
- 身份对象构造与赋值:令牌校验通过后,处理器会读取JWT载荷段的所有标准声明、自定义声明,将其转换为.NET平台的
Claim对象集合,基于该集合创建ClaimsIdentity身份实例,再包装为ClaimsPrincipal主体对象,直接赋值给当前请求的HttpContext.User属性。 - 后续组件读取声明:认证中间件执行完成后,后续运行的MVC管道、自定义授权过滤器等组件,访问
HttpContext.User.Claims拿到的就是已经解析完成的JWT声明集合,不需要重复做令牌解析操作。
注意:当前代码中
AddAuthentication()未显式指定默认认证方案,可能出现Cookie认证意外接管API请求认证的问题,建议显式将JwtBearer设置为默认认证方案,避免身份填充逻辑不符合预期。
内容的提问来源于stack exchange,提问作者Amir Dar
相关产品推荐
相关产品推荐

