Get claims from a WebAPI Controller - JWT Token,

后端 未结 4 1913
一向
一向 2020-12-05 18:53

I have built an application which uses JWT bearer authentication in ASP.NET Core. When authenticating I define some custom claims which i need to read in another WebAPI con

相关标签:
4条回答
  • 2020-12-05 19:12
    // Cast to ClaimsIdentity.
    var identity = HttpContext.User.Identity as ClaimsIdentity;
    
    // Gets list of claims.
    IEnumerable<Claim> claim = identity.Claims; 
    
    // Gets name from claims. Generally it's an email address.
    var usernameClaim = claim
        .Where(x => x.Type == ClaimTypes.Name)
        .FirstOrDefault();
    
    // Finds user.
    var userName = await _userManager
        .FindByNameAsync(usernameClaim.Value);
    
    if (userName == null)
    {
        return BadRequest();
    }
    
    // The rest of your code goes here...
    
    0 讨论(0)
  • 2020-12-05 19:13

    You should be able to retrieve a claims like this within your controller

    var identity = HttpContext.User.Identity as ClaimsIdentity;
    if (identity != null)
    {
        IEnumerable<Claim> claims = identity.Claims; 
        // or
        identity.FindFirst("ClaimName").Value;
    
    }
    

    If you wanted, you could write extension methods for the IPrincipal interface and retrieve claims using the code above, then retrieve them using (for example)

    HttpContext.User.Identity.MethodName();
    

    For completeness of the answer. To Decode the JWT token let's write a method to validate the token and extract the information.

    public static ClaimsPrincipal ValidateToken(string jwtToken)
        {
            IdentityModelEventSource.ShowPII = true;
    
            SecurityToken validatedToken;
            TokenValidationParameters validationParameters = new TokenValidationParameters();
    
            validationParameters.ValidateLifetime = true;
    
            validationParameters.ValidAudience = _audience.ToLower();
            validationParameters.ValidIssuer = _issuer.ToLower();
            validationParameters.IssuerSigningKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.Secret));
    
            ClaimsPrincipal principal = new JwtSecurityTokenHandler().ValidateToken(jwtToken, validationParameters, out validatedToken);
    
    
            return principal;
        }
    

    Now we can validate and extract the Claims by using:

    ValidateToken(tokenString)?.FindFirst("ClaimName")?.Value

    You should note that the ValidateToken method will return null value if the validation fails.

    0 讨论(0)
  • 2020-12-05 19:24

    In any controller from net core 2 that has gone through the authorize with the JwtBearerDefaults scheme, you can use:

     [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
     public ActionResult Index()
        {
            var user = User.FindFirst("Name").Value;
            //or if u want the list of claims
            var claims = User.Claims;
    
            return View();
        }
    
    0 讨论(0)
  • 2020-12-05 19:28

    There are a few JWT implementations for .NET Framework. If you use System.IdentityModel.Tokens.Jwt, when you validate the token you get a System.Security.Claims.ClaimsPrincipal that stores the token's claims in its "Claims" property. So you can get the token's claims as follows:

            string token = // ... read the token
            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
            TokenValidationParameters validationParameters = ...;
            SecurityToken securityToken;
            IPrincipal principal;
            try
            {
                // token validation
                principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);
                // Reading the "verificationKey" claim value:
                var vk = principal.Claims.SingleOrDefault(c => c.Type == "verificationKey").Value; 
            }
            catch
            {
                principal = null; // token validation error
            }
    

    Now where do you place this code? My choice was to implement the token validation as an authorization filter attribute derived from AuthorizationFilterAttribute. If you decorate a controller with the attribute, its OnAuthorization method is executed before every call to the controller's endpoints. You place the above code on the OnAuthorization method, and store the principal returned by the token validation on HttpContext.Current.User, that is also accessible on any endpoint on your API. http://blogs.quovantis.com/json-web-token-jwt-with-web-api/ is a nice sample of this implementation.

    0 讨论(0)
提交回复
热议问题