'Get JWT claims directly from the token, ASP Net Core 2.1
I working on an ASP Net Core 2.1 Web API. I've implemented successfully JWT within my project. Everything with the Authorization works fine.
Normally, when I need user claims, I know I can get them like this (E.g. Email claim):
var claimsIdentity = User.Identity as ClaimsIdentity;
var emailClaim = claimsIdentity.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Email);
The thing is, I am not in a controller that inherits from ControllerBase class, so I don't have any User object or [Authorize] attributes.
What I have though is the token itself.
e.g.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbiIsIm5iZiI6MTU2ODYzNjYxMywiZXhwIjoxNTY4NjQ3NDEzLCJpYXQiOjE1Njg2MzY2MTN9.ED9x_AOvkLQqutb09yh3Huyv0ygHp_i3Eli8WG2S9N4
I want to get the claims directly from the token, because:
- I have access to the token.
- I am not located in a Controller class and the request is not going through any
[Authorize]attributes, soIHttpContextAccessorcan't be used as well.
How can I achieve this in ASP Net Core 2.1? In case someone wants to see how I add the user claims:
var tokenDescriptor = new SecurityTokenDescriptor
{
Expires = DateTime.UtcNow.AddHours(3),
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, email),
new Claim(ClaimTypes.Email, email)
}),
SigningCredentials = new SigningCredentials(key: new SymmetricSecurityKey(key), algorithm: SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
I'm located in a class that derives from IDocumentFilter (Swagger class)
Solution 1:[1]
Here is a simple workaround:
var tokenDescriptor = new SecurityTokenDescriptor
{
Expires = DateTime.UtcNow.AddHours(3),
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, "[email protected]"),
new Claim(ClaimTypes.Email, "[email protected]")
}),
SigningCredentials = new SigningCredentials(key: new SymmetricSecurityKey(key), algorithm: SecurityAlgorithms.HmacSha256Signature)
};
var Securitytoken = new JwtSecurityTokenHandler().CreateToken(tokenDescriptor);
var tokenstring = new JwtSecurityTokenHandler().WriteToken(Securitytoken);
var token = new JwtSecurityTokenHandler().ReadJwtToken(tokenstring);
var claim = token.Claims.First(c => c.Type == "email").Value;
return claim;
Solution 2:[2]
For example in my current project I get claims by validation. Its refresh token, so I cant use [Authorize] attribute.
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
public ClaimsPrincipal ValidateRefreshToken(string refreshToken)
{
try
{
var validationParams = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(tokenSecurityKey),
ValidateLifetime = true
};
return new JwtSecurityTokenHandler().ValidateToken
(
refreshToken,
validationParams,
out SecurityToken token
);
}
catch (Exception e)
{
Log.Error(e.Message);
return null;
}
}
and then
var claims = ValidateRefreshToken(refreshToken);
...
var userIdString = claims.Claims.FirstOrDefault(x => x.Type == "userId")?.Value;
Solution 3:[3]
Here is an easy way to extract the claims:
public IEnumerable<Claim> ExtractClaims(string jwtToken)
{
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
JwtSecurityToken securityToken = (JwtSecurityToken)tokenHandler.ReadToken(jwtToken);
IEnumerable<Claim> claims = securityToken.Claims;
return claims;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Rena |
| Solution 2 | Victor Trusov |
| Solution 3 | Dennis Meissel |
