为什么 JWT 长度超过了?我们能处理吗?
Why JWT length is exceed ? can we handle it?
这是我生成 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。
这是我的 refresh/generate 新 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);
以上代码验证了我的过期令牌和returns原则。
我在这个原理中使用了声明来生成新的 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"
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();
声明的重命名是您必须注意的事情,这不是错误。这只是您必须接受并解决的生活事实。
这是我生成 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。
这是我的 refresh/generate 新 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);
以上代码验证了我的过期令牌和returns原则。 我在这个原理中使用了声明来生成新的 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"
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();
声明的重命名是您必须注意的事情,这不是错误。这只是您必须接受并解决的生活事实。