为啥 JWT 长度超过?我们能处理吗?

Posted

技术标签:

【中文标题】为啥 JWT 长度超过?我们能处理吗?【英文标题】:Why JWT length is exceed ? can we handle it?为什么 JWT 长度超过?我们能处理吗? 【发布时间】:2022-01-12 12:47:12 【问题描述】:

这是我生成 JWT 的代码。

//create security token handler
var tokenHandler = new JwtSecurityTokenHandler();
//create byte array of token key
var key = Encoding.ASCII.GetBytes(tokenKey);
//create token descriptor
var tokenDescriptor = new SecurityTokenDescriptor()

     Subject = new ClaimsIdentity(new Claim[]
     new Claim(ClaimTypes.Name,username),
     new Claim(ClaimTypes.Role,myrole),
     new Claim(ClaimTypes.Email,myemail) ),
 
     NotBefore = DateTime.UtcNow,
     Expires = DateTime.UtcNow.AddMinutes(1),
     SigningCredentials = new SigningCredentials(
     new SymmetricSecurityKey(key),
            SecurityAlgorithms.HmacSha256)
 ;
 var securityToken = tokenHandler.CreateToken(tokenDescriptor);
 var JWTtoken = tokenHandler.WriteToken(securityToken);   // this is my JWT.

上面的代码为我生成了访问令牌,我可以使用它来访问服务器资源。 当我想刷新我使用声明生成新 JWT 的令牌时。

这是我用于刷新/生成新 JWT 的代码。

var key = Encoding.ASCII.GetBytes(tokenKey);
var principle = tokenHandler.ValidateToken(token.Value,
new TokenValidationParameters()

      ValidateIssuerSigningKey = true,
      IssuerSigningKey = new SymmetricSecurityKey(key),
      ValidateIssuer = false,
      ValidateAudience = false,
      ValidateLifetime = false
  , out validatedToken);

以上代码验证我过期的令牌并返回原则。 我在这个原则中使用了声明来生成新的 JWT。

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

 var newToken = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);

这个新令牌的长度超过了之前的令牌。

 length of first token is 297
 length of new token is 516

我观察到 新令牌中的声明名称是有效负载中网址的更改。

在第一个令牌中声明

 "unique_name": "user1",
 "role": "Admin",
 "email": "Email",

申领新令牌

"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": "user1",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Admin",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress": "Email"

【问题讨论】:

声明类型名称的更改超过了令牌的长度。有什么建议吗? 你从哪里得到这个错误? 我从未说过我有错误或错误,也没有提及任何错误。只是想建议如何处理这种情况。并感谢您的回答。 如果对您有帮助,请随时接受我的回答,或者您需要我澄清一些事情吗? 【参考方案1】:

Microsoft 和 OAuth/OpenIDConnect 对声明名称应该是什么有不同的看法,因此当您的 .NET 代码收到令牌时,它会自动重命名一些声明。

禁用此映射的一种方法是使用以下命令清除映射:

// By default, Microsoft has some legacy claim mapping that converts
// standard JWT claims into proprietary ones. This removes those mappings.
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();

您必须注意此声明的重命名,这不是错误。这只是你必须接受和解决的生活事实。

【讨论】:

谢谢@Tore Nestenius。使用这行代码,我可以生成固定长度的 JWT。

以上是关于为啥 JWT 长度超过?我们能处理吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥数据报很少超过1500字节

为啥在 64 位平台上 BSTR 长度前缀为 4 个字节?

为啥我excel2007版 长度够长(1048576)却导出数据时说内存溢出、急!谢谢!谢谢!!

为啥我不能使用 `section .data:` 和 `section .text:` 在 C 中创建一个长度超过 61 个字符的 char 数组? [复制]

如何以及为啥使用 refresh_token 处理 jwt 令牌过期,还有另一种选择吗? [关闭]

我可以通过 BLE 宣传长度超过 31 个字节的字符串吗?