Authentifizierung und Autorisierung in Minimal-API-Apps

Minimal-APIs unterstützen alle in ASP.NET Core verfügbaren Authentifizierungs- und Autorisierungsoptionen und bieten einige zusätzliche Funktionen, um das Arbeiten mit der Authentifizierung zu verbessern.

Schlüsselkonzepte bei Authentifizierung und Autorisierung

Als Authentifizierung wird der Vorgang bezeichnet, mit dem die Identität eines Benutzers festgestellt wird. Autorisierung ist der Vorgang, mit dem ermittelt wird, ob ein Benutzer Zugriff auf eine Ressource hat. Authentifizierungs- und Autorisierungsszenarien teilen sich in ASP.NET Core ähnliche Implementierungssemantik. Die Authentifizierung wird vom Authentifizierungsdienst IAuthenticationService behandelt, der von der Authentifizierungsmiddleware verwendet wird. Die Autorisierung wird vom Autorisierungsdienst IAuthorizationService behandelt, der von der Autorisierungsmiddleware verwendet wird.

Der Authentifizierungsdienst verwendet registrierte Authentifizierungshandler, um Aktionen im Zusammenhang mit der Authentifizierung auszuführen. Beispielsweise ist eine authentifizierungsbezogene Aktion die Authentifizierung eines Benutzers oder das Abmelden eines Benutzers. Authentifizierungsschemas sind Namen, die verwendet werden, um einen Authentifizierungshandler und seine Konfigurationsoptionen eindeutig zu identifizieren. Authentifizierungshandler sind für die Implementierung der Strategien zur Authentifizierung und das Generieren der Ansprüche eines Benutzers bei einer bestimmten Authentifizierungsstrategie wie OAuth oder OIDC verantwortlich. Die Konfigurationsoptionen sind auch für die Strategie eindeutig und stellen dem Handler eine Konfiguration bereit, die sich auf das Authentifizierungsverhalten auswirkt, z. B. Umleitungs-URIs.

Es gibt zwei Strategien zum Bestimmen des Benutzerzugriffs auf Ressourcen auf der Autorisierungsebene:

  • Rollenbasierte Strategien bestimmen den Zugriff eines Benutzers basierend auf der zugewiesenen Rolle, z. B. Administrator oder User. Weitere Informationen zur rollenbasierten Autorisierung finden Sie in der Dokumentation zur rollenbasierten Autorisierung.
  • Anspruchsbasierte Strategien bestimmen den Zugriff eines Benutzers basierend auf Ansprüchen, die von einer zentralen Autorität ausgestellt werden. Weitere Informationen zur anspruchsbasierten Autorisierung finden Sie in der Dokumentation zur anspruchsbasierten Autorisierung.

In ASP.NET Core werden beide Strategien in einer Autorisierungsanforderung erfasst. Der Autorisierungsdienst verwendet Autorisierungshandler, um zu bestimmen, ob ein bestimmter Benutzer die auf eine Ressource angewendeten Autorisierungsanforderungen erfüllt.

Aktivieren der Authentifizierung in Minimal-Apps

Rufen Sie zum Aktivieren der Authentifizierung AddAuthentication auf, um die erforderlichen Authentifizierungsdienste beim Dienstanbieter der App zu registrieren.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication();
var app = builder.Build();

app.MapGet("/", () => "Hello World!");
app.Run();

In der Regel wird eine bestimmte Authentifizierungsstrategie verwendet. Im folgenden Beispiel wird die App mit Unterstützung für die JWT-bearerbasierte Authentifizierung konfiguriert. In diesem Beispiel werden die APIs im Microsoft.AspNetCore.Authentication.JwtBearer NuGet-Paket verwendet.

var builder = WebApplication.CreateBuilder(args);
// Requires Microsoft.AspNetCore.Authentication.JwtBearer
builder.Services.AddAuthentication().AddJwtBearer();
var app = builder.Build();

app.MapGet("/", () => "Hello World!");
app.Run();

Standardmäßig registriert die WebApplication automatisch die Authentifizierungs- und Autorisierungsmiddleware, wenn bestimmte Authentifizierungs- und Autorisierungsdienste aktiviert sind. Im folgenden Beispiel ist es nicht erforderlich, UseAuthentication oder UseAuthorization aufzurufen, um die Middleware zu registrieren, da WebApplication dies automatisch nach dem Aufruf von AddAuthentication oder AddAuthorization erledigt.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
var app = builder.Build();

app.MapGet("/", () => "Hello World!");
app.Run();

In einigen Fällen, z. B. beim Kontrollieren der Middlewarereihenfolge, ist es erforderlich, Authentifizierung und Autorisierung explizit zu registrieren. Im folgenden Beispiel wird die Authentifizierungsmiddleware ausgeführt, nachdem die CORS-Middleware ausgeführt wurde. Weitere Informationen zu Middleware und zu diesem automatischen Verhalten finden Sie unter Middleware in Minimal-API-Apps.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors();
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();

var app = builder.Build();

app.UseCors();
app.UseAuthentication();
app.UseAuthorization();

app.MapGet("/", () => "Hello World!");
app.Run();

Konfigurieren der Authentifizierungsstrategie

Authentifizierungsstrategien unterstützen in der Regel eine Vielzahl von Konfigurationen, die über Optionen geladen werden. Minimale Apps unterstützen Ladeoptionen aus der Konfiguration für die folgenden Authentifizierungsstrategien:

Das ASP.NET Core-Framework erwartet, dass diese Optionen im Authentication:Schemes:{SchemeName}-Abschnitt der Konfiguration gefunden werden. Im folgenden Beispiel werden zwei verschiedene Schemas Bearer und LocalAuthIssuer mit ihren jeweiligen Optionen definiert. Mit Option Authentication:DefaultScheme kann die verwendete Standardauthentifizierungsstrategie konfiguriert werden.

{
  "Authentication": {
    "DefaultScheme":  "LocalAuthIssuer",
    "Schemes": {
      "Bearer": {
        "ValidAudiences": [
          "https://localhost:7259",
          "http://localhost:5259"
        ],
        "ValidIssuer": "dotnet-user-jwts"
      },
      "LocalAuthIssuer": {
        "ValidAudiences": [
          "https://localhost:7259",
          "http://localhost:5259"
        ],
        "ValidIssuer": "local-auth"
      }
    }
  }
}

In Program.cs werden zwei JWT-Bearer-basierte Authentifizierungsstrategien mit Folgendem registriert:

  • Schemaname „Bearer“
  • Schemaname „LocalAuthIssuer“.

„Bearer“ ist das typische Standardschema in aktivierten JWT-Bearer-basierten Apps, aber das Standardschema kann überschrieben werden, indem die DefaultScheme-Eigenschaft wie im vorherigen Beispiel festgelegt wird.

Der Schemaname wird verwendet, um eine Authentifizierungsstrategie eindeutig zu identifizieren, und als Nachschlageschlüssel, wenn Authentifizierungsoptionen aus der Konfiguration aufgelöst werden, wie im folgenden Beispiel gezeigt:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication()
  .AddJwtBearer()
  .AddJwtBearer("LocalAuthIssuer");
  
var app = builder.Build();

app.MapGet("/", () => "Hello World!");
app.Run();

Konfigurieren von Autorisierungsrichtlinien in Minimal-Apps

Die Authentifizierung wird verwendet, um die Identität von Benutzern anhand einer API zu identifizieren und zu überprüfen. Die Autorisierung wird verwendet, um den Zugriff auf Ressourcen in einer API zu überprüfen, und wird durch den durch die AddAuthorization-Erweiterungsmethode registrierten IAuthorizationService erleichtert. Im folgenden Szenario wird eine /hello-Ressource hinzugefügt, für die ein Benutzer einen admin-Rollenanspruch mit einem greetings_api-Bereichsanspruch vorlegen muss.

Das Konfigurieren von Autorisierungsanforderungen für eine Ressource ist ein zweistufiger Prozess, der Folgendes erfordert:

  1. Globales Konfigurieren der Autorisierungsanforderungen in einer Richtlinie.
  2. Anwenden einzelner Richtlinien auf Ressourcen.

Im folgenden Code wird AddAuthorizationBuilder aufgerufen und führt folgende Aktionen aus:

  • Fügt dem DI-Container autorisierungsbezogene Dienste hinzu.
  • Gibt eine AuthorizationBuilder-Klasse zurück, die zum direkten Registrieren von Autorisierungsrichtlinien verwendet werden kann.

Der Code erstellt eine neue Autorisierungsrichtlinie namens admin_greetings, die zwei Autorisierungsanforderungen kapselt:

  • Eine rollenbasierte Anforderung über RequireRole für Benutzer mit einer admin-Rolle.
  • Eine anspruchsbasierte Anforderung über RequireClaim, dass der Benutzer einen greetings_api-Bereichsanspruch bereitstellen muss.

Die admin_greetings-Richtlinie wird als erforderliche Richtlinie für den /hello-Endpunkt bereitgestellt.

using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthorizationBuilder()
  .AddPolicy("admin_greetings", policy =>
        policy
            .RequireRole("admin")
            .RequireClaim("scope", "greetings_api"));

var app = builder.Build();

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

app.Run();

Verwenden von dotnet user-jwts für Entwicklungstests

In diesem Artikel wird eine App verwendet, die mit JWT-bearerbasierter Authentifizierung konfiguriert ist. Die JWT-bearerbasierte Authentifizierung erfordert, dass Clients im Anforderungsheader ein Token zur Überprüfung ihrer Identität und Ansprüche bereitstellen. In der Regel werden diese Token von einer zentralen Autorität wie einem Identitätsserver ausgestellt.

Bei der Entwicklung auf dem lokalen Computer kann das dotnet user-jwts-Tool zum Erstellen von Bearertoken verwendet werden.

dotnet user-jwts create

Hinweis

Wenn das Tool für ein Projekt aufgerufen wird, fügt es automatisch die Authentifizierungsoptionen hinzu, die dem zu appsettings.json generierten Token entsprechen.

Token können mit einer Vielzahl von Anpassungen konfiguriert werden. So wird beispielsweise ein Token für die Rolle admin und den Bereich greetings_api erstellt, das von der Autorisierungsrichtlinie im vorherigen Code erwartet wird:

dotnet user-jwts create --scope "greetings_api" --role "admin"

Das generierte Token kann dann als Teil des Headers im Testtool Ihrer Wahl gesendet werden. Z. B. mit curl:

curl -i -H "Authorization: Bearer {token}" https://localhost:{port}/hello

Weitere Informationen zum dotnet user-jwts-Tool finden Sie in der vollständigen Dokumentation.