web-dev-qa-db-fra.com

Obtenez des réclamations d'un contrôleur API Web - jeton JWT,

J'ai construit une application qui utilise l'authentification au porteur JWT dans ASP.NET Core. Lors de l'authentification, je définis certaines revendications personnalisées que je dois lire dans un autre contrôleur WebAPI afin d'exécuter certaines actions.

Des idées Comment puis-je y parvenir?

Voici à quoi ressemble mon code: (Le code a été simplifié)

public async Task<IActionResult> AuthenticateAsync([FromBody] UserModel user)
    {
        ..............

                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
                var tokenDescriptor = new SecurityTokenDescriptor
                {
                    Subject = new ClaimsIdentity(new Claim[]
                    {
                        new Claim("userSecurityKey", userDeserialized.SecurityKey.ToString()),
                        new Claim("timeStamp",timeStamp),
                        new Claim("verificationKey",userDeserialized.VerificationKey.ToString())

                    }),
                    Expires = DateTime.UtcNow.AddDays(7),
                    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
                        SecurityAlgorithms.HmacSha256Signature)
                };
                var token = tokenHandler.CreateToken(tokenDescriptor);
                var tokenString = tokenHandler.WriteToken(token);

     .................                           

    }

Un autre contrôleur: (Il doit lire la revendication "verificationKey".)

    [HttpGet]
    [Route("getcandidate")]
    public async Task<IActionResult> GetCandidateAsync()
    {

        try
        {
             ............    


            var verificationKey = //TODO: GET VerificationKey FROM THE TOKEN

            var verificationRecord = await service.GetVerificationRecordAsync(verificationKey);

            .................

        }
        catch (Exception)
        {
            return NotFound();
        }
    }
12
D.B

Vous devriez pouvoir récupérer une réclamation comme celle-ci dans votre contrôleur

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

}

Si vous le souhaitez, vous pouvez écrire des méthodes d'extension pour l'interface IPrincipal et récupérer des revendications à l'aide du code ci-dessus, puis les récupérer à l'aide (par exemple)

HttpContext.User.Identity.MethodName();

Pour l'exhaustivité de la réponse. Pour décoder le jeton JWT, écrivons une méthode pour valider le jeton et extraire les informations.

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;
    }

Nous pouvons maintenant valider et extraire les revendications en utilisant:

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

Vous devez noter que la méthode ValidateToken renverra la valeur null si la validation échoue.

29
Adriani6
// 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...
1
avg_bloke

Il existe quelques implémentations JWT pour .NET Framework. Si vous utilisez System.IdentityModel.Tokens.Jwt , lorsque vous validez le jeton, vous obtenez un System.Security. Claims.ClaimsPrincipal qui stocke les revendications du jeton dans sa propriété "Claims". Vous pouvez donc obtenir les revendications du jeton comme suit:

        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
        }

Maintenant, où placez-vous ce code? Mon choix a été d'implémenter la validation du jeton en tant qu'attribut de filtre d'autorisation dérivé de AuthorizationFilterAttribute . Si vous décorez un contrôleur avec l'attribut, sa méthode OnAuthorization est exécutée avant chaque appel aux points de terminaison du contrôleur. Vous placez le code ci-dessus sur la méthode OnAuthorization et stockez le principal retourné par la validation du jeton sur HttpContext.Current.User , qui est également accessible sur n'importe quel point de terminaison sur votre API. http://blogs.quovantis.com/json-web-token-jwt-with-web-api/ est un bel exemple de cette implémentation.

0
GBU