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 Mike Rousos
Bei Verwendung der richtlinienbasierten Autorisierung werden Richtlinien in der Regel registriert, indem AuthorizationOptions.AddPolicy
im Rahmen der Autorisierungsdienstkonfiguration aufgerufen wird. In einigen Szenarien ist es eventuell nicht möglich (oder wünschenswert), alle Autorisierungsrichtlinien auf diese Weise zu registrieren. In diesen Fällen können Sie über einen benutzerdefinierten IAuthorizationPolicyProvider
steuern, wie Autorisierungsrichtlinien bereitgestellt werden.
Beispiele für Szenarien, in denen ein benutzerdefinierter IAuthorizationPolicyProvider nützlich sein kann, umfassen etwa:
- Richtlinienauswertung über einen externen Dienst
- Verwendung vieler Richtlinien (z. B. für unterschiedliche Zimmernummern oder Altersstufen), sodass es nicht sinnvoll ist, jede einzelne Autorisierungsrichtlinie mit einem Aufruf von
AuthorizationOptions.AddPolicy
hinzuzufügen - Erstellen von Richtlinien zur Laufzeit basierend auf Informationen in einer externen Datenquelle (wie einer Datenbank) oder dynamisches Festlegen von Autorisierungsanforderungen über einen anderen Mechanismus
Im AspNetCore-GitHub-Repository können Sie Beispielcode anzeigen oder herunterladen. Laden Sie die ZIP-Datei des dotnet/AspNetCore-Repositorys herunter. Entzippen Sie die Datei. Navigieren Sie zum Projektordner src/Security/samples/CustomPolicyProvider.
Anpassen des Richtlinienabrufs
ASP.NET Core-Apps verwenden eine Implementierung der IAuthorizationPolicyProvider
-Schnittstelle, um Autorisierungsrichtlinien abzurufen. Standardmäßig wird DefaultAuthorizationPolicyProvider registriert und verwendet. DefaultAuthorizationPolicyProvider
gibt Richtlinien von den AuthorizationOptions
zurück, die in einem IServiceCollection.AddAuthorization
-Aufruf bereitgestellt werden.
Passen Sie dieses Verhalten an, indem Sie eine andere IAuthorizationPolicyProvider
-Implementierung im Dependency Injection-Container der App registrieren.
Die IAuthorizationPolicyProvider
-Schnittstelle enthält drei APIs:
- GetPolicyAsync gibt eine Autorisierungsrichtlinie für einen angegebenen Namen zurück.
- GetDefaultPolicyAsync gibt die Standardautorisierungsrichtlinie zurück (die Richtlinie, die für
[Authorize]
-Attribute verwendet wird, wenn keine Richtlinie angegeben wurde). - GetFallbackPolicyAsync gibt die Fallback-Autorisierungsrichtlinie zurück (die Richtlinie, die von der Autorisierungsmiddleware verwendet wird, wenn keine Richtlinie angegeben wurde).
Durch die Implementierung dieser APIs können Sie die Bereitstellung von Autorisierungsrichtlinien anpassen.
Beispiel für parametrisierte Autorisierungsattribute
Ein Szenario, in dem IAuthorizationPolicyProvider
nützlich ist, ist die Aktivierung benutzerdefinierter [Authorize]
-Attribute, deren Anforderungen von einem Parameter abhängig sind. Beispielsweise wurde in der Dokumentation zur richtlinienbasierten Autorisierung eine altersbasierte Richtlinie („AtLeast21“) als Beispiel verwendet. Wenn in einer App Benutzer*innen unterschiedlichen Alters verschiedene Controlleraktionen zur Verfügung gestellt werden sollen, kann es hilfreich sein, viele verschiedene altersbasierte Richtlinien zu verwenden. Anstatt in AuthorizationOptions
alle von der Anwendung benötigten unterschiedlichen altersbasierten Richtlinien zu registrieren, können Sie die Richtlinien dynamisch mit einem benutzerdefinierten IAuthorizationPolicyProvider
generieren. Zur einfacheren Verwendung der Richtlinien können Sie Aktionen mit einem benutzerdefinierten Autorisierungsattribut wie [MinimumAgeAuthorize(20)]
kommentieren.
Benutzerdefinierte Autorisierungsattribute
Autorisierungsrichtlinien werden durch ihre Namen identifiziert. Das zuvor beschriebene benutzerdefinierte MinimumAgeAuthorizeAttribute
muss Argumente einer Zeichenfolge zuordnen, über die die entsprechende Autorisierungsrichtlinie abgerufen werden kann. Dies können Sie durch Ableiten von AuthorizeAttribute
und Umschließen der AuthorizeAttribute.Policy
-Eigenschaft durch die Age
-Eigenschaft erreichen.
internal class MinimumAgeAuthorizeAttribute : AuthorizeAttribute
{
const string POLICY_PREFIX = "MinimumAge";
public MinimumAgeAuthorizeAttribute(int age) => Age = age;
// Get or set the Age property by manipulating the underlying Policy property
public int Age
{
get
{
if (int.TryParse(Policy.Substring(POLICY_PREFIX.Length), out var age))
{
return age;
}
return default(int);
}
set
{
Policy = $"{POLICY_PREFIX}{value.ToString()}";
}
}
}
Dieser Attributtyp verfügt über die Zeichenfolge Policy
basierend auf dem hartcodierten Präfix ("MinimumAge"
) und einem Integer, der über den Konstruktor übergeben wird.
Sie können ihn auf Aktionen ebenso anwenden wie andere Authorize
-Attribute, mit der Ausnahme, dass ein Integer als Parameter verwendet wird.
[MinimumAgeAuthorize(10)]
public IActionResult RequiresMinimumAge10()
Benutzerdefinierter IAuthorizationPolicyProvider
Mit dem benutzerdefinierten MinimumAgeAuthorizeAttribute
ist das Anfordern von Autorisierungsrichtlinien für jedes gewünschte Mindestalter eine einfache Aufgabe. Als Nächstes muss sichergestellt werden, dass Autorisierungsrichtlinien für alle diese Altersgruppen verfügbar sind. Hierbei ist ein IAuthorizationPolicyProvider
nützlich.
Bei Verwendung von MinimumAgeAuthorizationAttribute
entsprechen die Namen der Autorisierungsrichtlinien dem Muster "MinimumAge" + Age
. Daher sollte der benutzerdefinierte IAuthorizationPolicyProvider
Autorisierungsrichtlinien wie folgt generieren:
- Analysieren des Alters anhand des Richtliniennamens
- Erstellen einer neuen
AuthorizationPolicy
mitAuthorizationPolicyBuilder
- In diesem Beispiel und den folgenden Beispiel wird davon ausgegangen, dass Benutzer*innen über ein cookie authentifiziert werden. Der
AuthorizationPolicyBuilder
sollte mit mindestens einem Autorisierungsschemanamen erstellt werden oder immer erfolgreich sein. Andernfalls gibt es keine Informationen zum Bereitstellen einer Aufforderung für die Benutzer*innen, und eine Ausnahme wird ausgelöst. - Hinzufügen von Anforderungen zur Richtlinie basierend auf dem Alter mit
AuthorizationPolicyBuilder.AddRequirements
. In anderen Szenarien können Sie stattdessenRequireClaim
,RequireRole
oderRequireUserName
verwenden.
internal class MinimumAgePolicyProvider : IAuthorizationPolicyProvider
{
const string POLICY_PREFIX = "MinimumAge";
// Policies are looked up by string name, so expect 'parameters' (like age)
// to be embedded in the policy names. This is abstracted away from developers
// by the more strongly-typed attributes derived from AuthorizeAttribute
// (like [MinimumAgeAuthorize()] in this sample)
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
if (policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase) &&
int.TryParse(policyName.Substring(POLICY_PREFIX.Length), out var age))
{
var policy = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme);
policy.AddRequirements(new MinimumAgeRequirement(age));
return Task.FromResult(policy.Build());
}
return Task.FromResult<AuthorizationPolicy>(null);
}
}
Mehrere Autorisierungsrichtlinienanbieter
Beachten Sie bei der Verwendung benutzerdefinierter IAuthorizationPolicyProvider
-Implementierungen, dass ASP.NET Core nur eine Instanz von IAuthorizationPolicyProvider
verwendet. Wenn ein benutzerdefinierter Anbieter nicht in der Lage ist, Autorisierungsrichtlinien für alle verwendeten Richtliniennamen bereitzustellen, sollte er auf einen anderen Anbieter zurückgreifen.
Beispiel: Eine Anwendung benötigt sowohl benutzerdefinierte Altersrichtlinien als auch herkömmlichen rollenbasierten Richtlinienabruf. Eine solche Anwendung könnte einen benutzerdefinierten Autorisierungsrichtlinienanbieter verwenden, der folgendermaßen vorgeht:
- Er versucht, die Richtliniennamen zu analysieren.
- Er ruft einen anderen Richtlinienanbieter auf (z. B.
DefaultAuthorizationPolicyProvider
), wenn der Richtlinienname kein Alter enthält.
Die oben dargestellte Beispielimplementierung von IAuthorizationPolicyProvider
kann für die Verwendung des DefaultAuthorizationPolicyProvider
aktualisiert werden, indem ein zweiter Richtlinienanbieter im Konstruktor erstellt wird. Dieser dient für den Fall, dass der Richtlinienname nicht mit dem erwarteten Muster „MinimumAge“ + Alter übereinstimmt.
private DefaultAuthorizationPolicyProvider BackupPolicyProvider { get; }
public MinimumAgePolicyProvider(IOptions<AuthorizationOptions> options)
{
// ASP.NET Core only uses one authorization policy provider, so if the custom implementation
// doesn't handle all policies it should fall back to an alternate provider.
BackupPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
}
Anschließend kann die GetPolicyAsync
-Methode so aktualisiert werden, dass der BackupPolicyProvider
verwendet wird, anstatt NULL zurückzugeben:
...
return BackupPolicyProvider.GetPolicyAsync(policyName);
Standardrichtlinie
Zusätzlich zur Bereitstellung benannter Autorisierungsrichtlinien muss ein benutzerdefinierter IAuthorizationPolicyProvider
GetDefaultPolicyAsync
implementieren, damit eine Autorisierungsrichtlinie für [Authorize]
-Attribute ohne angegebenen Richtliniennamen bereitgestellt wird.
In vielen Fällen erfordert dieses Autorisierungsattribut lediglich eine/n authentifizierte/n Benutzer*in, sodass Sie die erforderliche Richtlinie durch einen Aufruf von RequireAuthenticatedUser
erstellen können:
public Task<AuthorizationPolicy> GetDefaultPolicyAsync() =>
Task.FromResult(new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build());
Wie bei allen Aspekten eines benutzerdefinierten IAuthorizationPolicyProvider
können Sie dies nach Bedarf anpassen. In einigen Fällen kann es wünschenswert sein, die Standardrichtlinie von einem Fallback-IAuthorizationPolicyProvider
abzurufen.
Fallbackrichtlinie
Ein benutzerdefinierter IAuthorizationPolicyProvider
kann optional GetFallbackPolicyAsync
implementieren, um eine Richtlinie bereitzustellen, die beim Kombinieren von Richtlinien und bei nicht angegebenen Richtlinien verwendet wird. Wenn GetFallbackPolicyAsync
nicht NULL, sondern eine Richtlinie zurückgibt, wird die zurückgegebene Richtlinie von der Autorisierungsmiddleware verwendet, wenn keine Richtlinien für die Anforderung angegeben werden.
Wenn keine Fallbackrichtlinie erforderlich ist, kann der Anbieter null
zurückgeben oder auf den Fallbackanbieter zurückgreifen:
public Task<AuthorizationPolicy> GetFallbackPolicyAsync() =>
Task.FromResult<AuthorizationPolicy>(null);
Verwenden eines benutzerdefinierten IAuthorizationPolicyProvider
Um benutzerdefinierte Richtlinien von einem IAuthorizationPolicyProvider
zu verwenden, müssen Sie Folgendes ausführen:
Registrieren Sie die entsprechenden
AuthorizationHandler
-Typen mit Dependency Injection (beschrieben unter Richtlinienbasierte Autorisierung) wie bei allen richtlinienbasierten Autorisierungsszenarien.Registrieren Sie den benutzerdefinierten
IAuthorizationPolicyProvider
-Typ in der Dependency Injection-Dienstsammlung der App inStartup.ConfigureServices
, um den Standardrichtlinienanbieter zu ersetzen.services.AddSingleton<IAuthorizationPolicyProvider, MinimumAgePolicyProvider>();
Ein vollständiges Beispiel für einen benutzerdefinierten IAuthorizationPolicyProvider
ist im dotnet/aspnetcore-GitHub-Repository verfügbar.