web-dev-qa-db-fra.com

Obtenez les revendications du jeton JWT dans l'API ASP.NET Core 2.0

J'utilise une authentification mixte dans mon application Web et API ASP.NET Core 2.0. Signifiant à la fois les cookies et maintenant l'ajout de JWT token.

La partie Web de l'application utilise des cookies et dans la partie API, je veux utiliser le jeton JWT.

Ma question est de savoir comment obtenir les réclamations de JWT token? Dans mes contrôleurs Web, je peux simplement utiliser HttpContext.User; pour enregistrer les revendications dans un cookie. Comment le gérer dans mes méthodes d'API où je veux utiliser JWT token?

Voici mon AuthenticationBuilder:

public static void MyAuthenticationConfig(IServiceCollection services, IConfiguration configuration)
{
   services.AddAuthentication(options =>
   {
      options.DefaultAuthenticateScheme = "myApp_cookie";
      options.DefaultChallengeScheme = "myApp_cookie";
    })
    .AddCookie("myApp_cookie", options =>
    {
      options.AccessDeniedPath = "/Unauthorized";
      options.LoginPath = "/Login";
    })
    .AddCookie("social_auth_cookie")
    .AddOAuth("LinkedIn", options =>
    {
      options.SignInScheme = "social_auth_cookie";

      options.ClientId = "my_client_id";
      options.ClientSecret = "my_secret";

      options.CallbackPath = "/linkedin-callback";

      options.AuthorizationEndpoint = "https://www.linkedin.com/oauth/v2/authorization";
      options.TokenEndpoint = "https://www.linkedin.com/oauth/v2/accessToken";
      options.UserInformationEndpoint = "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address,picture-url,picture-urls::(original))";

      options.Scope.Add("r_basicprofile");
      options.Scope.Add("r_emailaddress");

      options.Events = new OAuthEvents
      {
         OnCreatingTicket = OnCreatingTicketLinkedInCallBack,
         OnTicketReceived = OnTicketReceivedCallback
       };
    })
    .AddFacebook(options =>
    {
        options.SignInScheme = "social_auth_cookie";
        options.AppId = "my_app_is";
        options.AppSecret = "my_secret";
        options.Events = new OAuthEvents
        {
           OnCreatingTicket = OnCreatingTicketFacebookCallback,
           OnTicketReceived = OnTicketReceivedCallback
         };
     })
     .AddGoogle(options =>
     {
         options.SignInScheme = "social_auth_cookie";
         options.ClientId = "my_id.apps.googleusercontent.com";
         options.ClientSecret = "my_secret";
         options.CallbackPath = "/google-callback";
         options.Events = new OAuthEvents
         {
             OnCreatingTicket = OnCreatingTicketGoogleCallback,
             OnTicketReceived = OnTicketReceivedCallback
         };
      })
      .AddJwtBearer("JwtBearer", jwtBearerOptions =>
      {
         jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
         {
             ValidateIssuerSigningKey = true,
             IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("my_secret")),

             ValidateIssuer = true,
             ValidIssuer = "my-api",

             ValidateAudience = true,
             ValidAudience = "my-client",

             ValidateLifetime = true,

             ClockSkew = TimeSpan.FromMinutes(5)
        };
    });
}
6
Sam

Normalement, les revendications de JWT sont automatiquement ajoutées à ClaimsIdentity.

La source:
https: //github.com/AzureAD/Azure-activedirectory-identitymodel-extensions-for-dotnet/blob/af5e5c2b0100e8348c63e2d2bb45612e2080841e/src/System.IdentityModelTwL ).

Vous devriez donc pouvoir simplement utiliser la propriété 'User' de la classe de base 'Controller'.

public async Task<IActionResult> Get()
{
    // TODO Move 'Claims' extraction code to an extension method
    var address = User.Claims.Where('GET THE NEEDED CLAIM');
    ...
}

Je n'ai jamais eu de problème pour obtenir les revendications d'un jeton JWT. Mais je n'ai utilisé que IdentityServer4.AccessTokenValidation jusqu'à présent. Mais en interne, il utilise l'afik de Microsoft JWT Handler.

11
ErazerBrecht

Impossible de commenter car mon message serait trop long, alors faites un message séparé à la place.

Si vous suivez le guide/lien publié par ErazerBrecht, les réclamations sont en effet stockées dans l'utilisateur ClaimsPrincipal. J'ai créé une méthode d'extension pour récupérer la revendication.

Notez que j'utilise un Enum pour enregistrer mes réclamations. J'utilise un dictionnaire pour transmettre mes revendications à la méthode qui génère mon jeton, donc ma clé de revendication doit toujours être unique.

La méthode d'extension:

public static string GetClaim(this ClaimsPrincipal claimsPrincipal, JwtClaim jwtClaim)
{
  var claim = claimsPrincipal.Claims.Where(c => c.Type == jwtClaim.ToString()).FirstOrDefault();

  if (claim == null)
  {
      throw new JwtClaimNotFoundException(jwtClaim);
  }

  return claim.Value;
}

Appelez ça comme:

var userId = User.GetClaim(JwtClaim.UserId);
1
BartKrul