Freigeben über


Informationen zur Autorisierung in .NET Microservices und Webanwendungen

Tipp

Dieser Inhalt ist ein Auszug aus dem eBook .NET Microservices Architecture for Containerized .NET Applications, verfügbar auf .NET Docs oder als kostenlose herunterladbare PDF, die offline gelesen werden kann.

.NET Microservices-Architektur für containerisierte .NET-Anwendungen eBook-Cover-Thumbnail.

Nach der Authentifizierung müssen ASP.NET Core Web-APIs den Zugriff autorisieren. Dieser Prozess ermöglicht es einem Dienst, APIs für einige authentifizierte Benutzer zur Verfügung zu stellen, aber nicht für alle. Die Autorisierung kann basierend auf den Rollen der Benutzer oder basierend auf einer benutzerdefinierten Richtlinie erfolgen, die das Prüfen von Ansprüchen oder andere Heuristiken umfassen kann.

Das Einschränken des Zugriffs auf eine ASP.NET Core MVC-Route ist so einfach wie das Anwenden eines Authorize-Attributs auf die Aktionsmethode (oder auf die Klasse des Controllers, wenn alle Aktionen des Controllers eine Autorisierung erfordern), wie im folgenden Beispiel gezeigt:

public class AccountController : Controller
{
    public ActionResult Login()
    {
    }

    [Authorize]
    public ActionResult Logout()
    {
    }
}

Standardmäßig beschränkt das Hinzufügen eines Authorize-Attributs ohne Parameter den Zugriff auf authentifizierte Benutzer für diesen Controller oder diese Aktion. Um eine API weiter einzuschränken, die nur für bestimmte Benutzer verfügbar ist, kann das Attribut erweitert werden, um erforderliche Rollen oder Richtlinien anzugeben, die Benutzer erfüllen müssen.

Implementieren der rollenbasierten Autorisierung

ASP.NET Core Identity verfügt über ein integriertes Rollenkonzept. Zusätzlich zu Benutzern speichert ASP.NET Core Identity Informationen zu verschiedenen Rollen, die von der Anwendung verwendet werden, und verfolgt, welche Benutzer welchen Rollen zugewiesen sind. Diese Zuweisungen können programmgesteuert mit dem Typ geändert werden, der RoleManager Rollen im permanenten Speicher aktualisiert, und dem Typ, der UserManager Rollen von Benutzern gewähren oder widerrufen kann.

Wenn Sie sich mit JWT-Bearertoken authentifizieren, füllt die ASP.NET Core JWT Bearer Authentication Middleware die Rollen eines Benutzers basierend auf Rollenansprüchen im Token auf. Um den Zugriff auf eine MVC-Aktion oder einen Controller auf Benutzer in bestimmten Rollen zu beschränken, können Sie einen Roles-Parameter in die Authorize-Anmerkung (Attribut) einschließen, wie im folgenden Codefragment gezeigt:

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlPanelController : Controller
{
    public ActionResult SetTime()
    {
    }

    [Authorize(Roles = "Administrator")]
    public ActionResult ShutDown()
    {
    }
}

In diesem Beispiel können nur Benutzer in den Rollen "Administrator" oder "PowerUser" auf APIs im ControlPanel-Controller zugreifen (z. B. die SetTime-Aktion ausführen). Die ShutDown-API ist weiter eingeschränkt, um den Zugriff nur auf Benutzer in der Administratorrolle zuzulassen.

Damit sich ein Benutzer in mehreren Rollen befindet, verwenden Sie mehrere Autorisierungsattribute, wie im folgenden Beispiel gezeigt:

[Authorize(Roles = "Administrator, PowerUser")]
[Authorize(Roles = "RemoteEmployee ")]
[Authorize(Policy = "CustomPolicy")]
public ActionResult API1 ()
{
}

In diesem Beispiel muss ein Benutzer zum Aufrufen von API1 Folgendes ausführen:

  • Er muss in der Rolle „Administrator“ oder „PowerUser“ sein, und

  • er muss in der Rolle „RemoteEmployee“ sein, und

  • er muss die Bedingungen eines benutzerdefinierten Handlers für die CustomPolicy-Autorisierung erfüllen.

Implementieren der richtlinienbasierten Autorisierung

Benutzerdefinierte Autorisierungsregeln können auch mithilfe von Autorisierungsrichtlinien geschrieben werden. Dieser Abschnitt enthält eine Übersicht. Weitere Informationen finden Sie im ASP.NET Autorisierungs-Workshop.

Benutzerdefinierte Autorisierungsrichtlinien werden in der Startup.ConfigureServices-Methode mithilfe der AddAuthorization-Methode des Dienstes registriert. Diese Methode verwendet einen Delegaten, der ein AuthorizationOptions-Argument konfiguriert.

services.AddAuthorization(options =>
{
    options.AddPolicy("AdministratorsOnly", policy =>
        policy.RequireRole("Administrator"));

    options.AddPolicy("EmployeesOnly", policy =>
        policy.RequireClaim("EmployeeNumber"));

    options.AddPolicy("Over21", policy =>
        policy.Requirements.Add(new MinimumAgeRequirement(21)));
});

Wie im Beispiel gezeigt, können Richtlinien verschiedenen Arten von Anforderungen zugeordnet werden. Nachdem die Richtlinien registriert wurden, können sie auf eine Aktion oder einen Controller angewendet werden, indem der Name der Richtlinie als Argument "Policy" des Attributs "Authorize" übergeben wird (z. B. [Authorize(Policy="EmployeesOnly")]). Richtlinien können mehrere Anforderungen haben, nicht nur eine (wie in diesen Beispielen gezeigt).

Im vorherigen Beispiel ist der erste AddPolicy-Aufruf nur eine alternative Methode zur Autorisierung nach Rolle. Wenn [Authorize(Policy="AdministratorsOnly")] sie auf eine API angewendet wird, können nur Benutzer in der Administratorrolle darauf zugreifen.

Der zweite AddPolicy Aufruf zeigt eine einfache Möglichkeit, zu verlangen, dass ein bestimmter Anspruch für den Benutzer vorhanden sein sollte. Die RequireClaim Methode akzeptiert optional auch erwartete Werte für den Anspruch. Wenn Werte angegeben werden, wird die Anforderung nur erfüllt, wenn der Benutzer sowohl einen Anspruch vom richtigen Typ als auch einen der angegebenen Werte hat. Wenn Sie die JWT-Bearerauthentifizierungs-Middleware verwenden, sind alle JWT-Eigenschaften als Benutzeransprüche verfügbar.

Die interessantesten hier gezeigte Richtlinie ist in der dritten AddPolicy Methode, da sie eine benutzerdefinierte Autorisierungsanforderung verwendet. Mithilfe von benutzerdefinierten Autorisierungsanforderungen können Sie eine große Kontrolle darüber haben, wie die Autorisierung ausgeführt wird. Damit dies funktioniert, müssen Sie diese Typen implementieren:

  • Ein Anforderungstyp, der von IAuthorizationRequirement Feldern abgeleitet wird und felder enthält, die die Details der Anforderung angeben. Im Beispiel ist dies ein Altersfeld für den Beispieltyp MinimumAgeRequirement .

  • Ein Handler, der implementiert AuthorizationHandler<TRequirement>, wobei T der Typ ist IAuthorizationRequirement , den der Handler erfüllen kann. Der Handler muss die Methode implementieren, mit der HandleRequirementAsync überprüft wird, ob ein angegebener Kontext, der Informationen über den Benutzer enthält, die Anforderung erfüllt.

Wenn der Benutzer die Anforderung erfüllt, gibt ein Anruf context.Succeed an, dass der Benutzer autorisiert ist. Wenn es mehrere Möglichkeiten gibt, wie ein Benutzer möglicherweise eine Autorisierungsanforderung erfüllt, können mehrere Handler erstellt werden.

Neben der Registrierung benutzerdefinierter Richtlinienanforderungen mit AddPolicy-Aufrufen müssen Sie auch über die Abhängigkeitsinjektion benutzerdefinierte Anforderungshandler registrieren (services.AddTransient<IAuthorizationHandler, MinimumAgeHandler>()).

Ein Beispiel für eine benutzerdefinierte Autorisierungsanforderung und einen Handler zum Überprüfen des Alters eines Benutzers (basierend auf einem DateOfBirth Anspruch) ist in der ASP.NET Core-Autorisierungsdokumentation verfügbar.

Autorisierung und minimale APIs

ASP.NET unterstützt minimale APIs als Alternative zu controllerbasierten APIs. Autorisierungsrichtlinien sind die empfohlene Methode zum Konfigurieren der Autorisierung für minimale APIs, wie in diesem Beispiel veranschaulicht:

// Program.cs
builder.Services.AddAuthorizationBuilder()
  .AddPolicy("admin_greetings", policy =>
        policy
            .RequireRole("admin")
            .RequireScope("greetings_api"));

// build the app

app.MapGet("/hello", () => "Hello world!")
  .RequireAuthorization("admin_greetings");

Weitere Ressourcen