Get JWT claims directly from the token, ASP Net Core 2.1

13,765

Solution 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

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;
Share:
13,765
G.Dimov
Author by

G.Dimov

Passionate about what I develop and code. (◕‿◕✿)

Updated on June 24, 2022

Comments

  • G.Dimov
    G.Dimov almost 2 years

    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:

    1. I have access to the token.
    2. I am not located in a Controller class and the request is not going through any [Authorize] attributes, so IHttpContextAccessor can'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)