ASP.NET Core WebApi自定义Claim映射到Identity.Name方法
首先直接回应你的疑问:你关于ClaimsIdentity.Name取值逻辑的认知不准确。ClaimsIdentity.Name并不会固定查找类型为name的Claim,它的取值规则是读取当前身份实例NameClaimType属性指定的Claim类型对应的值。.NET平台JWT Bearer认证的默认配置中,NameClaimType对应的是WS-Identity标准的声明类型http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name(对应静态常量ClaimTypes.Name),你生成Token时自定义的username类型Claim不在默认映射规则内,因此HttpContext.User.Identity.Name会返回null。
你可以任选以下两种方案解决问题,都适配你当前简洁的教学项目代码风格:
方案1:调整Token生成逻辑,使用框架默认识别的标准声明类型
不需要修改认证配置,只需要替换生成Claim时的用户名声明类型即可,修改后的claims定义代码如下:var claims = new List<Claim> { new("id", user.Id.ToString()), // 替换为框架默认识别的Name声明类型 new(ClaimTypes.Name, user.Username) }; if (user.Username == "pbrause") claims.Add(new("weatherForecast", "true"));方案2:调整JWT Bearer认证配置,自定义Name属性对应的Claim类型
如果你希望保留自定义的usernameClaim写法、不改动Token生成逻辑,可以在注册JWT Bearer认证服务时,手动指定NameClaimType为你自定义的username,配置示例如下:builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { // 保留你原本的所有校验配置(密钥、Issuer、Audience校验规则等) NameClaimType = "username", // 新增该行,指定Name属性读取username类型的Claim ValidateIssuer = true, ValidIssuer = "me", ValidateAudience = true, ValidAudience = "you", IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(builder.Configuration["AppSettings:JwtSecret"])) // 其他你原有配置保持不变即可 }; });
两种方案任意一种配置完成后,HttpContext.User.Identity.Name就能正确获取到你存储的用户名信息。
内容的提问来源于stack exchange,提问作者Andreas

