You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET Core 6.0中从JWT安全令牌读取自定义声明值

解决方案

1. 自定义声明丢失的核心修复

这是由于ASP.NET Core JWT处理程序默认开启了声明类型映射,会自动将短声明名转换为XML SOAP标准的长URI格式,未匹配到映射规则的自定义声明会被过滤。
在Program.cs的AddAuthentication配置前添加一行代码清除默认映射:

// 清除默认声明类型映射,保留自定义声明的原始名称
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

builder.Services.AddAuthentication(m => {
    m.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    m.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(conf => {
    conf.RequireHttpsMetadata = false;
    conf.SaveToken = true;
    conf.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidIssuer = Configuration["JWT-Issuer"],
        ValidAudience = Configuration["JWT-Issuer"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT-Key"])),
        ClockSkew = TimeSpan.Zero,
        // 可选:添加签名密钥校验提升安全性
        ValidateIssuerSigningKey = true,
        // 可选:如果要使用[Authorize(Roles="xxx")]特性,指定角色声明的类型
        RoleClaimType = "Role"
    };
});

配置完成后,你的自定义声明TEMP、UserName都会原样保留在User.Claims中。


2. 读取声明代码优化

清除映射后,内置声明的类型也会还原为短名称,你可以直接用原始声明名读取,无需匹配长URI:

// 读取邮箱
string Email = User.FindFirstValue(JwtRegisteredClaimNames.Email);
// 读取自定义TEMP声明
string FirstName = User.FindFirstValue("TEMP");

FindFirstValue是官方封装的简化方法,找不到对应声明时会返回null,避免空引用异常。


3. 显式设置DefaultAuthenticateScheme返回401的问题修复

你现在只设置DefaultScheme就可以覆盖所有身份验证相关的默认方案,本身不需要额外调整。如果要显式配置DefaultAuthenticateScheme,只需检查两个配置点:

  • 确认中间件顺序正确,Program.cs中必须先调用app.UseAuthentication(),再调用app.UseAuthorization(),顺序错误会直接导致401
  • 如果你的项目同时集成了ASP.NET Core Identity,不要使用AddIdentity扩展方法,改用AddIdentityCore,前者会默认覆盖身份验证方案为Cookie,导致JWT配置失效

不需要创建自定义身份验证方案,按上述配置调整即可解决所有问题。

内容的提问来源于stack exchange,提问作者Saqlain Mushtaq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 10:06:03