Est-il possible de prendre en charge plusieurs émetteurs de jetons JWT dans ASP.NET Core 2? Je souhaite fournir une API pour un service externe et je dois utiliser deux sources de jetons JWT - Firebase et les émetteurs de jetons JWT personnalisés. Dans ASP.NET core, je peux définir l'authentification JWT pour le schéma d'authentification du porteur, mais uniquement pour une autorité:
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://securetoken.google.com/my-firebase-project"
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "my-firebase-project"
ValidateAudience = true,
ValidAudience = "my-firebase-project"
ValidateLifetime = true
};
}
Je peux avoir plusieurs émetteurs et publics, mais je ne peux pas définir plusieurs autorités.
Réponses:
Vous pouvez totalement réaliser ce que vous voulez:
services .AddAuthentication() .AddJwtBearer("Firebase", options => { options.Authority = "https://securetoken.google.com/my-firebase-project" options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = "my-firebase-project" ValidateAudience = true, ValidAudience = "my-firebase-project" ValidateLifetime = true }; }) .AddJwtBearer("Custom", options => { // Configuration for your custom // JWT tokens here }); services .AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes("Firebase", "Custom") .Build(); });
Passons en revue les différences entre votre code et celui-là.
AddAuthentication
n'a pas de paramètreSi vous définissez un schéma d'authentification par défaut, à chaque demande, le middleware d'authentification essaiera d'exécuter le gestionnaire d'authentification associé au schéma d'authentification par défaut. Puisque nous avons maintenant deux schémas d'authentification opssibles, il est inutile d'en exécuter un.
Utilisez une autre surcharge de
AddJwtBearer
Chaque
AddXXX
méthode unique pour ajouter une authentification a plusieurs surcharges:Maintenant, comme vous utilisez la même méthode d'authentification deux fois mais que les schémas d'authentification doivent être uniques, vous devez utiliser la deuxième surcharge.
Mettre à jour la politique par défaut
Étant donné que les demandes ne seront plus authentifiées automatiquement, le fait de placer des
[Authorize]
attributs sur certaines actions entraînera le rejet des demandes et unHTTP 401
sera émis.Puisque ce n'est pas ce que nous voulons parce que nous voulons donner aux gestionnaires d'authentification une chance d'authentifier la demande, nous changeons la politique par défaut du système d'autorisation en indiquant à la fois les schémas d'authentification
Firebase
etCustom
doivent être essayés pour authentifier la demande.Cela ne vous empêche pas d'être plus restrictif sur certaines actions; l'
[Authorize]
attribut a uneAuthenticationSchemes
propriété qui vous permet de remplacer les schémas d'authentification valides.Si vous avez des scénarios plus complexes, vous pouvez utiliser l' autorisation basée sur des stratégies . Je trouve que la documentation officielle est excellente.
Imaginons que certaines actions ne soient disponibles que pour les jetons JWT émis par Firebase et doivent avoir une revendication avec une valeur spécifique; vous pouvez le faire de cette façon:
// Authentication code omitted for brevity services .AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes("Firebase", "Custom") .Build(); options.AddPolicy("FirebaseAdministrators", new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes("Firebase") .RequireClaim("role", "admin") .Build()); });
Vous pouvez ensuite utiliser
[Authorize(Policy = "FirebaseAdministrators")]
sur certaines actions.Un dernier point à noter: si vous attrapez des
AuthenticationFailed
événements et n'utilisez rien d'autre que la premièreAddJwtBearer
stratégie, vous pouvez voir queIDX10501: Signature validation failed. Unable to match key...
cela est dû au fait que le système vérifie chacunAddJwtBearer
à son tour jusqu'à ce qu'il obtienne une correspondance. L'erreur peut généralement être ignorée.la source
Authorization : Bearer <token>
cela, l'en-tête êtreAuthorization : Firebase <token>
par exemple? Lorsque j'ai essayé cette solution, j'ai eu l'erreur: "Aucun gestionnaire d'authentification n'est enregistré pour le schéma 'Bearer'.".AddJwtBearer
appels de méthode.[Authorize]
attribut vide .C'est une extension de la réponse de Mickaël Derriey.
Notre application a une exigence d'autorisation personnalisée que nous résolvons à partir d'une source interne. Nous utilisions Auth0 mais passons à l'authentification de compte Microsoft à l'aide d'OpenID. Voici le code légèrement modifié de notre démarrage ASP.Net Core 2.1. Pour les futurs lecteurs, cela fonctionne dès la rédaction de cet article pour les versions spécifiées. L'appelant utilise l'id_token d'OpenID sur les demandes entrantes passées en tant que jeton Bearer. J'espère que cela aide quelqu'un d'autre à essayer de faire une conversion d'autorité d'identité autant que cette question et cette réponse m'ont aidé.
const string Auth0 = nameof(Auth0); const string MsaOpenId = nameof(MsaOpenId); string domain = "https://myAuth0App.auth0.com/"; services.AddAuthentication() .AddJwtBearer(Auth0, options => { options.Authority = domain; options.Audience = "https://myAuth0Audience.com"; }) .AddJwtBearer(MsaOpenId, options => { options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { ValidateAudience = true, ValidAudience = "00000000-0000-0000-0000-000000000000", ValidateIssuer = true, ValidIssuer = "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0", ValidateIssuerSigningKey = true, RequireExpirationTime = true, ValidateLifetime = true, RequireSignedTokens = true, ClockSkew = TimeSpan.FromMinutes(10), }; options.MetadataAddress = "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0/.well-known/openid-configuration"; } ); services.AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes( Auth0, MsaOpenId ) .Build(); var approvedPolicyBuilder = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes(Auth0, MsaOpenId) ; approvedPolicyBuilder.Requirements.Add(new HasApprovedRequirement(domain)); options.AddPolicy("approved", approvedPolicyBuilder.Build()); });
la source