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

JWT刷新后长度异常增大的原因是什么?有什么处理方案?

问题原因

这是.NET中JwtSecurityTokenHandler类的默认Claim类型映射机制导致的:

  • 第一次生成JWT时,你用ClaimTypes枚举定义的声明本质是内置的URI格式常量,生成令牌时JwtSecurityTokenHandler会按照内置映射规则,自动把这些长URI映射为unique_name、role、email这类短名称写入JWT的Payload。
  • 当你验证旧令牌获取ClaimsPrincipal时,入站验证逻辑又会自动把JWT里的短声明名称,反向映射回原本的长URI格式作为Claim的Type存储在内存中。
  • 刷新令牌时你直接把这些带有长URI Type的Claim传入新令牌的生成逻辑,此时没有触发反向的短名映射,直接把长URI作为Payload的键写入,最终导致令牌长度翻倍。

解决方案

方案1:全局关闭默认Claim类型映射(推荐)

在程序启动入口(如.NET 6+的Program.cs文件顶部)添加以下代码,清空默认的入站、出站Claim映射规则:

// 清空入站Claim类型映射,验证令牌时不会把短名转成长URI
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
// 清空出站Claim类型映射,生成令牌时不会自动转换Claim名称
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();

修改后验证令牌得到的ClaimsPrincipal中的Claim Type会和JWT Payload里的短名完全一致,刷新生成的新令牌也会沿用短名,长度和初始令牌一致。

方案2:刷新令牌时手动转换Claim名称

如果不想修改全局映射,可以在刷新令牌时手动处理Claim,替换掉长URI前缀:

var claims = principle.Claims.Select(c => 
{
    var shortType = c.Type switch
    {
        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" => "unique_name",
        "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" => "role",
        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" => "email",
        _ => c.Type
    };
    return new Claim(shortType, c.Value);
});

var jwtSecurityToken = new JwtSecurityToken(
    claims: claims.ToArray(),
    notBefore: DateTime.UtcNow,
    expires: DateTime.UtcNow.AddMinutes(1),
    signingCredentials: new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256)
);

方案3:生成初始令牌时直接使用短字符串作为Claim类型

创建Claim时不使用ClaimTypes的常量,直接传入自定义短名称,从根源避免映射转换:

Subject = new ClaimsIdentity(new Claim[]{
    new Claim("unique_name",username),
    new Claim("role",myrole),
    new Claim("email",myemail) 
}),

内容的提问来源于stack exchange,提问作者Yuvraj Mule

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:36:00