Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Von Damien Bowden
Claims können aus beliebigen Benutzer- oder Identitätsdaten generiert werden, die über einen vertrauenswürdigen Identitätsanbieter oder ASP.NET Core Identity ausgegeben werden können. Eine Anspruchsaussage ist ein Name-Wert-Paar, das darstellt, was das Subjekt ist, nicht was das Subjekt tun kann.
In diesem Artikel wird beschrieben, wie Sie Ansprüche mithilfe eines OpenID Connect-Clients konfigurieren und zuordnen und die folgenden Aufgaben behandeln:
- Festlegen von Namen- und Rollenansprüchen
- Zurücksetzen der Anspruchsnamespaces
- Anpassen und Erweitern der Ansprüche mit der TransformAsync Methode
Zuordnen von Ansprüchen mit openID Connect-Authentifizierung
Die Profilansprüche können im id_token zurückgegeben werden, das nach einer erfolgreichen Authentifizierung zurückgegeben wird. Die ASP.NET Core-Client-App benötigt nur den Profilbereich. Wenn Sie id_token für Ansprüche verwenden, ist keine zusätzliche Anspruchszuordnung erforderlich.
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Für den obigen Code benötigen Sie das NuGet-Paket Microsoft.AspNetCore.Authentication.OpenIdConnect.
Eine andere Möglichkeit zum Abrufen der Benutzeransprüche besteht darin, die OpenID Connect-API für Benutzerinformationen zu verwenden. Die ASP.NET Core-Client-App verwendet die Eigenschaft GetClaimsFromUserInfoEndpoint, um die Konfiguration zu erledigen. In diesem Szenario müssen Sie explizit die erforderlichen Ansprüche mithilfe der MapUniqueJsonKey Methode angeben. Andernfalls sind in der Client-App nur die name, given_name und email Standardansprüche verfügbar. Die im id_token enthaltenen Ansprüche werden standardmäßig zugeordnet.
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.MapUniqueJsonKey("preferred_username",
"preferred_username");
options.ClaimActions.MapUniqueJsonKey("gender", "gender");
});
var app = builder.Build();
// Code removed for brevity.
Hinweis
Der standardmäßige OpenID Connect Handler verwendet Pushed Authorization Requests (PAR), wenn das Discovery-Dokument des Identitätsanbieters Unterstützung für PAR angibt. Der allgemeine Speicherort für das Ermittlungsdokument des Identitätsanbieters ist der Ordner ".well-known/openid-configuration" . Wenn Sie PAR in der Clientkonfiguration für den Identitätsanbieter nicht verwenden können, kann PAR mithilfe der PushedAuthorizationBehavior Option deaktiviert werden.
builder.Services
.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect("oidc", oidcOptions =>
{
// Other provider-specific configuration goes here.
// The default value is PushedAuthorizationBehavior.UseIfAvailable.
// 'OpenIdConnectOptions' does not contain a definition for 'PushedAuthorizationBehavior'
// and no accessible extension method 'PushedAuthorizationBehavior' accepting a first argument
// of type 'OpenIdConnectOptions' could be found
oidcOptions.PushedAuthorizationBehavior = PushedAuthorizationBehavior.Disable;
});
Um sicherzustellen, dass die Authentifizierung nur dann erfolgreich ist, wenn PAR verwendet wird, verwenden Sie stattdessen den Enumerationstyp PushedAuthorizationBehavior.Require. Diese Änderung führt außerdem bei OpenIdConnectEvents ein neues OnPushAuthorization-Ereignis ein, das verwendet werden kann, um die gepushte Autorisierungsanforderung anzupassen oder sie manuell zu behandeln. Weitere Informationen finden Sie im API-Vorschlag in GitHub Problem "dotnet/aspnetcore" #51686 - Support for Pushed Authorization Requests in OidcHandler.
Zuordnen von Namens- und Rollenansprüchen
Der name Anspruch und role Anspruch werden standardeigenschaften im ASP.NET Core HTTP-Kontext zugeordnet. Manchmal müssen Sie unterschiedliche Ansprüche für die Standardeigenschaften verwenden, oder der Namensanspruch und der Rollenanspruch stimmen nicht mit den Standardwerten überein. Die Ansprüche können mithilfe der TokenValidationParameters Eigenschaft zugeordnet und bei Bedarf auf einen beliebigen Anspruch festgelegt werden. Die Werte aus den Ansprüchen können direkt in der HttpContext-Eigenschaft User.Identity.Name und den Rollen verwendet werden.
Wenn die User.Identity.Name Eigenschaft keinen Wert aufweist oder die Rollen fehlen, überprüfen Sie die Werte in den zurückgegebenen Ansprüchen, und legen Sie die NameClaimType Werte und die RoleClaimType Werte fest. Die von der Clientauthentifizierung zurückgegebenen Ansprüche können im HTTP-Kontext angezeigt werden.
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
// Other options...
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "email"
//, RoleClaimType = "role"
};
});
Anspruchsnamespaces, Standardnamespaces
ASP.NET Core fügt einigen bekannten Ansprüchen Standardnamespaces hinzu. Die Standardansprüche sind in der App möglicherweise nicht erforderlich. Optional können Sie die hinzugefügten Namespaces deaktivieren und die exakten Claims verwenden, die der OpenID Connect-Server erstellt hat.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
// Code removed for brevity.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
// Code removed for brevity.
Wenn Sie die Namespaces pro Schema und nicht global deaktivieren müssen, können Sie die MapInboundClaims = false Option verwenden.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.MapInboundClaims = false;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
// Code removed for brevity.
Erweitern oder Hinzufügen von benutzerdefinierten Ansprüchen mithilfe von "IClaimsTransformation"
Mithilfe der Schnittstelle IClaimsTransformation können Sie der ClaimsPrincipal-Klasse zusätzliche Ansprüche hinzufügen. Für die Schnittstelle ist eine einzelne Methode erforderlich. TransformAsync Diese Methode kann mehrmals aufgerufen werden. Fügen Sie nur dann einen neuen Anspruch hinzu, wenn er im ClaimsPrincipal noch nicht vorhanden ist. Ein ClaimsIdentity-Objekt wird erstellt, um die neuen Claims hinzuzufügen, und kann dem ClaimsPrincipal hinzugefügt werden.
using Microsoft.AspNetCore.Authentication;
using System.Security.Claims;
public class MyClaimsTransformation : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity();
var claimType = "myNewClaim";
if (!principal.HasClaim(claim => claim.Type == claimType))
{
claimsIdentity.AddClaim(new Claim(claimType, "myClaimValue"));
}
principal.AddIdentity(claimsIdentity);
return Task.FromResult(principal);
}
}
Die IClaimsTransformation-Schnittstelle und die MyClaimsTransformation-Klasse können als Dienst registriert werden:
builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
Zuordnen von Ansprüchen von externen Identitätsanbietern
Wenn Sie Ansprüche von externen Identitätsanbietern für Ihre App zuordnen möchten, lesen Sie Persist andere Ansprüche und Token von externen Anbietern in ASP.NET Core.
Ansprüche können von allen Benutzer- oder Identitätsdaten erstellt werden, die mit einem vertrauenswürdigen Identitätsanbieter oder ASP.NET Core-Identität ausgestellt werden können. Ein Anspruch ist ein Name-Wert-Paar, das das Subjekt darstellt und nicht das, was das Subjekt tun kann. In diesem Artikel werden die folgenden Themenbereiche behandelt:
- Konfigurieren und Zuordnen von Ansprüchen mit einem OpenID Connect-Client
- Festlegen von Namens- und Rollenanspruch
- Zurücksetzen der Anspruchsnamespaces
- Anpassen und Erweitern der Ansprüche mit TransformAsync
Zuordnung von Ansprüchen mithilfe der OpenID Connect-Authentifizierung
Die Profilansprüche können im id_token zurückgegeben werden, das nach einer erfolgreichen Authentifizierung zurückgegeben wird. Die ASP.NET Core-Client-App benötigt nur den Profilbereich. Wenn Sie das id_token für Ansprüche verwenden, ist keine zusätzliche Anspruchszuordnung erforderlich.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
Eine andere Möglichkeit zum Abrufen der Benutzeransprüche besteht darin, die OpenID Connect-API für Benutzerinformationen zu verwenden. Die ASP.NET Core-Clientanwendung verwendet die Eigenschaft GetClaimsFromUserInfoEndpoint, um dies zu konfigurieren. Ein wichtiger Unterschied gegenüber den ersten Einstellungen besteht darin, dass Sie die benötigten Ansprüche mit der MapUniqueJsonKey-Methode angeben müssen, da sonst nur die Standardansprüche name, given_name und email in der Clientanwendung verfügbar sind. Die im id_token enthaltenen Ansprüche werden standardmäßig zugeordnet. Dies ist der Hauptunterschied gegenüber der ersten Option. Sie müssen einige der von Ihnen benötigten Ansprüche explizit definieren.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.MapUniqueJsonKey("preferred_username", "preferred_username");
options.ClaimActions.MapUniqueJsonKey("gender", "gender");
});
Zuordnen von Namens- und Rollenansprüchen
Der Name-Anspruch und der Role-Anspruch werden Standardeigenschaften im ASP.NET Core HTTP-Kontext zugewiesen. Mitunter müssen unterschiedliche Ansprüche für die Standardeigenschaften verwendet werden, oder der Namens- und der Rollenanspruch entsprechen nicht den Standardwerten. Die Ansprüche können über die TokenValidationParameters-Eigenschaft zugeordnet und bei Bedarf auf einen beliebigen Anspruch festgelegt werden. Die Werte aus den Ansprüchen können direkt in der HttpContext-Eigenschaft User.Identity.Name und in den Rollen verwendet werden.
Wenn User.Identity.Name keinen Wert aufweist oder die Rollen fehlen, überprüfen Sie die Werte in den zurückgegebenen Ansprüchen, und legen Sie die Werte NameClaimType und RoleClaimType fest. Die von der Clientauthentifizierung zurückgegebenen Ansprüche können im HTTP-Kontext angezeigt werden.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
// other options...
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "email",
// RoleClaimType = "role"
};
});
Anspruchsnamespaces, Standardnamespaces
ASP.NET Core fügt einigen bekannten Ansprüchen Standardnamespaces hinzu, die in der App möglicherweise nicht benötigt werden. Optional können Sie diese hinzugefügten Namespaces deaktivieren und genau die Claims verwenden, die der OpenID Connect-Server erstellt hat.
public void Configure(IApplicationBuilder app)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
Erweitern oder Hinzufügen von benutzerdefinierten Ansprüchen mit IClaimsTransformation
Mithilfe der Schnittstelle IClaimsTransformation können Sie der ClaimsPrincipal-Klasse zusätzliche Ansprüche hinzufügen. Die Schnittstelle erfordert eine einzige TransformAsync-Methode. Diese Methode wird möglicherweise mehrmals aufgerufen. Fügen Sie nur dann einen neuen Anspruch hinzu, wenn er nicht bereits im ClaimsPrincipal vorhanden ist. Eine ClaimsIdentity wird erstellt, um die neuen Ansprüche hinzuzufügen, und diese kann dem ClaimsPrincipal hinzugefügt werden.
public class MyClaimsTransformation : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity();
var claimType = "myNewClaim";
if (!principal.HasClaim(claim => claim.Type == claimType))
{
claimsIdentity.AddClaim(new Claim(claimType, "myClaimValue"));
}
principal.AddIdentity(claimsIdentity);
return Task.FromResult(principal);
}
}
Die IClaimsTransformation-Schnittstelle und die MyClaimsTransformation-Klasse können in der ConfigureServices-Methode als Dienst hinzugefügt werden.
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
Erweitern oder Hinzufügen benutzerdefinierter Ansprüche in ASP.NET Core Identity
Weitere Informationen finden Sie im folgenden Dokument:
Hinzufügen von Ansprüchen zu Identity mit IUserClaimsPrincipalFactory
Zuordnen von Ansprüchen von externen Identitätsanbietern
Weitere Informationen finden Sie im folgenden Dokument:
Speichern zusätzlicher Ansprüche und Token von externen Anbietern in ASP.NET Core