web-dev-qa-db-fra.com

Impossible d'obtenir les revendications du jeton JWT avec ASP.NET Core

J'essaie de faire une implémentation très simple de l'authentification de porteur JWT avec ASP.NET Core. Je retourne une réponse d'un contrôleur un peu comme ceci:

    var identity = new ClaimsIdentity();
    identity.AddClaim(new Claim(ClaimTypes.Name, applicationUser.UserName));
        var jwt = new JwtSecurityToken(
             _jwtOptions.Issuer,
             _jwtOptions.Audience,
             identity.Claims,
             _jwtOptions.NotBefore,
             _jwtOptions.Expiration,
             _jwtOptions.SigningCredentials);

       var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

       return new JObject(
           new JProperty("access_token", encodedJwt),
           new JProperty("token_type", "bearer"),
           new JProperty("expires_in", (int)_jwtOptions.ValidFor.TotalSeconds),
           new JProperty(".issued", DateTimeOffset.UtcNow.ToString())
       );

J'ai un middleware Jwt pour les demandes entrantes:

app.UseJwtBearerAuthentication(new JwtBearerOptions
{
     AutomaticAuthenticate = true,
     AutomaticChallenge = true,
     TokenValidationParameters = tokenValidationParameters
});

Cela semble fonctionner pour protéger les ressources avec l'attribut authorize, mais les revendications ne s'affichent jamais.

    [Authorize]
    public async Task<IActionResult> Get()
    {
        var user = ClaimsPrincipal.Current.Claims; // Nothing here
8
user888734

Vous ne pouvez pas utiliser ClaimsPricipal.Current dans une application ASP.NET Core, car elle n'est pas définie par le moteur d'exécution. Vous pouvez lire https://github.com/aspnet/Security/issues/322 pour plus d'informations.

Au lieu de cela, envisagez d'utiliser la propriété User, exposée par ControllerBase.

13
Pinpoint

Accédez à User.Claims au lieu de ClaimsPrinciple.Current.Claims.

De Introduction à l'identité sur docs.asp.net :

... dans la méthode d'action HomeController.Index, vous pouvez afficher les détails de User.Claims

Voici le code source pertinent du référentiel MVC: 

public ClaimsPrincipal User
{
   get
   {
       return HttpContext?.User;
   }
}
7
Shaun Luttin

Dans ASP.NET Core 2.0, vous pouvez lire les revendications JWT telles que Shaun décrites ci-dessus. Si vous recherchez uniquement l'ID utilisateur (assurez-vous de l'avoir déjà ajouté à la revendication en utilisant le nom de la revendication "Sub"), vous pouvez utiliser les exemples suivants pour lire en fonction de votre cas d'utilisation:

Lecture de l'identifiant d'utilisateur:

    public class AccountController : Controller
    {
        [Authorize]
        [HttpGet]
        public async Task<IActionResult> MethodName()
        {
            var userId = _userManager.GetUserId(HttpContext.User);
            //...
            return Ok();
        }
    }

Lire d'autres revendications:

    public class AccountController : Controller
    {
        [Authorize]
        [HttpGet]
        public async Task<IActionResult> MethodName()
        {
            var rolesClaim = HttpContext.User.Claims.Where( c => c.Type == ClaimsIdentity.DefaultRoleClaimType).FirstOrDefault();
            //...
            return Ok();
        }
    }
2
Tony

Grâce à cette solution, vous pouvez accéder à User.Identiy et à ses revendications dans les contrôleurs lorsque vous utilisez des jetons Jwt:

étape 1: créer un JwtTokenMiddleware:

public static class JwtTokenMiddleware
{
    public static IApplicationBuilder UseJwtTokenMiddleware(
      this IApplicationBuilder app,
      string schema = "Bearer")
    {
        return app.Use((async (ctx, next) =>
        {
            IIdentity identity = ctx.User.Identity;
            if ((identity != null ? (!identity.IsAuthenticated ? 1 : 0) : 1) != 0)
            {
                AuthenticateResult authenticateResult = await ctx.AuthenticateAsync(schema);
                if (authenticateResult.Succeeded && authenticateResult.Principal != null)
                    ctx.User = authenticateResult.Principal;
            }
            await next();
        }));
    }
}

étape 2: utilisez-le dans Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();
    app.UseJwtTokenMiddleware();
}
1
Morteza Zabihi