This is my code to generate 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.
Above code generated access token for me I can use it to access server resources. When I want to refresh the the token I used claims to generate new JWT.
Here is my code for refresh/generate new 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);
Above code validate my expired token and returns principle. I used claims in this principle to generate new 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 this new token is exceeds than previous token.
length of first token is 297
length of new token is 516
I observed claim names in new token is changes to web address in payload.
Claims in first token
"unique_name": "user1",
"role": "Admin",
"email": "Email",
Claims in new token
"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"
CodePudding user response:
Microsoft and OAuth/OpenIDConnect have different opinions on what the claim names should be, so when your .NET code receives a token, then it will rename some of the claims automatically.
One way to disable this mapping is to clear the map using:
// 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();
This renaming of claims is something you have to be aware of and this is not a bug. Its just a fact of life that you have to accept and work around.