Ist es möglich, mehrere JWT-Token-Aussteller in ASP.NET Core 2 zu unterstützen? Ich möchte eine API für externe Dienste bereitstellen und muss zwei Quellen für JWT-Token verwenden - Firebase- und benutzerdefinierte JWT-Token-Aussteller. In ASP.NET Core kann ich die JWT-Authentifizierung für das Bearer-Authentifizierungsschema festlegen, jedoch nur für eine Behörde:
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
};
}
Ich kann mehrere Emittenten und Zielgruppen haben, aber nicht mehrere Behörden festlegen.
Antworten:
Sie können voll und ganz erreichen, was Sie wollen:
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(); });
Lassen Sie uns die Unterschiede zwischen Ihrem Code und diesem durchgehen.
AddAuthentication
hat keinen ParameterWenn Sie ein Standardauthentifizierungsschema festlegen, versucht die Authentifizierungs-Middleware bei jeder einzelnen Anforderung, den dem Standardauthentifizierungsschema zugeordneten Authentifizierungshandler auszuführen. Da wir jetzt zwei mögliche Authentifizierungsschemata haben, macht es keinen Sinn, eines davon auszuführen.
Verwenden Sie eine andere Überladung von
AddJwtBearer
Jede einzelne
AddXXX
Methode zum Hinzufügen einer Authentifizierung weist mehrere Überladungen auf:Da Sie dieselbe Authentifizierungsmethode zweimal verwenden, die Authentifizierungsschemata jedoch eindeutig sein müssen, müssen Sie die zweite Überladung verwenden.
Aktualisieren Sie die Standardrichtlinie
Da die Anforderungen nicht mehr automatisch authentifiziert werden, werden beim Anlegen von
[Authorize]
Attributen für einige Aktionen die Anforderungen abgelehnt und eineHTTP 401
ausgegeben.Da das ist nicht das, was wir wollen , weil wir die Authentifizierungs - Handler eine Chance zu authentifizieren , die Anforderung geben wollen, müssen wir die Standardrichtlinie des Autorisierungssystems verändern sowohl die durch die Angabe
Firebase
undCustom
sollte Systeme Authentifizierung werden versucht , die Anforderung zu authentifizieren.Das hindert Sie nicht daran, einige Aktionen restriktiver zu gestalten. Das
[Authorize]
Attribut verfügt über eineAuthenticationSchemes
Eigenschaft, mit der Sie überschreiben können, welche Authentifizierungsschemata gültig sind.Wenn Sie komplexere Szenarien haben, können Sie die richtlinienbasierte Autorisierung verwenden . Ich finde die offizielle Dokumentation großartig.
Stellen wir uns vor, einige Aktionen stehen nur JWT-Token zur Verfügung, die von Firebase ausgestellt wurden, und müssen einen Anspruch mit einem bestimmten Wert haben. Sie könnten es so machen:
// 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()); });
Sie können dann
[Authorize(Policy = "FirebaseAdministrators")]
einige Aktionen verwenden.Ein letzter zu beachtender Punkt: Wenn Sie
AuthenticationFailed
Ereignisse abfangen und etwas anderes als die ersteAddJwtBearer
Richtlinie verwenden, wird möglicherweise Folgendes angezeigt:IDX10501: Signature validation failed. Unable to match key...
Dies wird dadurch verursacht, dass das System jedeAddJwtBearer
nacheinander überprüft, bis eine Übereinstimmung erzielt wird. Der Fehler kann normalerweise ignoriert werden.quelle
Authorization : Bearer <token>
der HeaderAuthorization : Firebase <token>
zum Beispiel? Beim Ausprobieren dieser Lösung wurde folgende Fehlermeldung angezeigt: "Für das Schema 'Bearer' ist kein Authentifizierungshandler registriert.".AddJwtBearer
Methodenaufrufe.[Authorize]
Attribut dekorieren .Dies ist eine Erweiterung von Mickaël Derrieys Antwort.
Unsere App hat eine benutzerdefinierte Autorisierungsanforderung, die wir aus einer internen Quelle lösen. Wir haben Auth0 verwendet, wechseln jedoch mit OpenID zur Microsoft-Kontoauthentifizierung. Hier ist der leicht bearbeitete Code aus unserem ASP.Net Core 2.1-Start. Für zukünftige Leser funktioniert dies ab diesem Zeitpunkt für die angegebenen Versionen. Der Aufrufer verwendet das id_token von OpenID für eingehende Anforderungen, die als Bearer-Token übergeben werden. Ich hoffe, es hilft jemand anderem, der versucht, eine Identitätsautoritätskonvertierung durchzuführen, genauso wie mir diese Frage und Antwort geholfen hat.
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()); });
quelle