Authentifizierung und Autorisierung in ASP.NET Core Blazor

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

In diesem Artikel wird die ASP.NET Core-Unterstützung für die Konfiguration und Verwaltung der Sicherheit in Blazor-Apps beschrieben.

Das Sicherheitsszenario unterscheidet sich je nach Autorisierungscode, der serverseitig und clientseitig in Blazor-Apps ausgeführt wird. Bei Autorisierungscode, der auf dem Server ausgeführt wird, können Autorisierungsprüfungen Zugriffsregeln für Bereiche der App und Komponenten erzwingen. Da clientseitige Codeausführung manipuliert werden kann, ist Autorisierungscode, der auf dem Client ausgeführt wird, nicht vertrauenswürdig, um Zugriffsregeln absolut zu erzwingen oder die Anzeige clientseitiger Inhalte zu steuern.

Wenn die Erzwingung von Autorisierungsregelen gewährleistet sein muss, implementieren Sie keine Autorisierungsprüfungen im clientseitigen Code. Erstellen Sie eine Blazor-Web-App, die nur auf serverseitigem Rendering (SSR) für Autorisierungsprüfungen und die Regelerzwingung basiert.

Autorisierungskonventionen von Razor Pages gelten nicht für routingfähige Razor-Komponenten. Wenn eine nicht routingfähige Razor-Komponente auf einer Seite einer Razor Pages-App eingebettet wird, wirken sich die Autorisierungskonventionen der Seite indirekt auf die Razor-Komponente sowie auf den Rest des Seiteninhalts aus.

Wenn die Erzwingung von Autorisierungsregeln und die Sicherheit von Daten und Code gewährleistet sein müssen, entwickeln Sie keine clientseitige App. Entwickeln Sie eine Blazor Server-App.

Autorisierungskonventionen von Razor Pages gelten nicht für routingfähige Razor-Komponenten. Wenn eine nicht routingfähige Razor-Komponente auf einer Seite einer Razor Pages-App eingebettet wird, wirken sich die Autorisierungskonventionen der Seite indirekt auf die Razor-Komponente sowie auf den Rest des Seiteninhalts aus.

ASP.NET Core Identity ist für die Arbeit im Kontext der HTTP-Anforderungs- und -Antwortkommunikation konzipiert, was in der Regel nicht dem Blazor-Modell für die Kommunikation zwischen App-Client und Server entspricht. ASP.NET Core-Apps, welche die Benutzerverwaltung mit ASP.NET Core Identity umsetzen, sollten für eine Identity Benutzeroberfläche Razor Seiten anstelle von Razor Komponenten verwenden, z. B. Benutzerregistrierung, Anmelden, Abmelden und andere Benutzerverwaltungsaufgaben. Das Erstellen von Razor-Komponenten, die Identity-Aufgaben direkt verarbeiten, ist für mehrere Szenarien möglich, wird aber von Microsoft weder empfohlen noch unterstützt.

ASP.NET Core-Abstraktionen, wie z. B. SignInManager<TUser> und UserManager<TUser>, werden nicht in Razor Komponenten unterstützt. Weitere Informationen zur Verwendung von ASP.NET Core Identity mit Blazor finden Sie unter ASP.NET Core Identity in eine serverseitige Blazor App einbauen.

Hinweis

Die Codebeispiele in diesem Artikel verwenden Nullwerte zulassende Verweistypen (Nullable Reference Types, NRTs) und die statische Analyse des NULL-Zustands des .NET-Compilers, die in ASP.NET Core in .NET 6 oder höher unterstützt werden. Entfernen Sie bei ASP.NET Core 5.0 oder früher die NULL-Typbezeichnung (?) aus den Beispielen in diesem Artikel.

Unterstützung des Schutzes vor Fälschung

Die Blazor-Vorlage:

Die AntiforgeryToken-Komponente rendert ein Token zum Schutz gegen Fälschungen als ausgeblendetes Feld. Diese Komponente wird automatisch hinzugefügt, um Instanzen (EditForm) zu bilden. Weitere Informationen finden Sie unter Übersicht über ASP.NET Core Blazor Formulare.

Der AntiforgeryStateProvider-Dienst bietet Zugriff auf ein Token zum Schutz vor Fälschungen, das der aktuellen Sitzung zugeordnet ist. Fügen Sie den Dienst ein, und rufen Sie die GetAntiforgeryToken()-Methode auf, um die aktuelle AntiforgeryRequestToken abzurufen. Weitere Informationen finden Sie unter Aufrufen einer Web-API über eine ASP.NET Core Blazor-App.

Blazor speichert Anforderungstoken im Komponentenstatus, wodurch sichergestellt wird, dass Token zum Schutz vor Fälschungen für interaktive Komponenten verfügbar sind, auch wenn sie keinen Zugriff auf die Anforderung haben.

Hinweis

Antiforgery-Entschärfung ist nur erforderlich, wenn Formulardaten an den Server übermittelt werden, die als application/x-www-form-urlencoded, multipart/form-dataoder text/plain da dies die einzigen gültigen Formularenctypessind.

Weitere Informationen finden Sie in den folgenden Ressourcen:

Authentifizierung

Blazor verwendet die vorhandenen ASP.NET Core-Authentifizierungsmechanismen, um die Identität des Benutzers festzustellen. Der genaue Mechanismus hängt davon ab, ob die Blazor-App serverseitig oder clientseitig gehostet wird.

Serverseitige Blazor-Authentifizierung

Serverseitig wird das interaktiv dargestellte Blazor über eine SignalR-Verbindung mit dem Client ausgeführt. Die Authentifizierung in SignalR-basierten Apps wird verarbeitet, wenn die Verbindung hergestellt wird. Die Authentifizierung kann auf einem cookie oder einem anderen Bearertoken basieren, aber die Authentifizierung wird über den SignalR-Hub und vollständig innerhalb der Verbindung verwaltet.

Der integrierte Dienst AuthenticationStateProvider ruft die Daten zum Authentifizierungsstatus von HttpContext.User von ASP. NET Core ab. Auf diese Weise lässt sich der Authentifizierungsstatus in bestehende Authentifizierungsmechanismen von ASP.NET Core integrieren.

IHttpContextAccessor/HttpContext in Razor-Komponenten

IHttpContextAccessor muss mit interaktivem Rendering vermieden werden, da kein gültiger HttpContext verfügbar ist.

IHttpContextAccessor kann für Komponenten verwendet werden, die auf dem Server statisch gerendert werden. Es wird jedoch empfohlen, dies nach Möglichkeit zu vermeiden.

HttpContext kann nur in statisch gerenderten Stammkomponenten für allgemeine Aufgaben als kaskadierender Parameter verwendet werden, z. B. beim Überprüfen und Ändern von Headern oder anderen Eigenschaften in der App-Komponente (Components/App.razor). Der Wert lautet immer null zum interaktiven Rendern.

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

Für Szenarios, in denen HttpContext in interaktiven Komponenten erforderlich ist, empfehlen wir, die Daten über den permanenten Komponentenstatus vom Server zu übertragen. Weitere Informationen finden Sie unter Zusätzliche serverseitige Sicherheitsszenarien für Blazor in ASP.NET Core.

Verwenden Sie IHttpContextAccessor/HttpContext nicht direkt oder indirekt in den Razor-Komponenten serverseitiger Blazor-Apps. Blazor-Apps werden außerhalb des ASP.NET Core-Pipelinekontexts ausgeführt. Die Verfügbarkeit von HttpContext in IHttpContextAccessor kann nicht sichergestellt, und es ist auch nicht gewährleistet, dass HttpContext den Kontext zum Starten der Blazor-App enthält.

Der empfohlene Ansatz für das Übergeben des Anforderungsstatus an die Blazor-App erfolgt über Stammkomponentenparameter während des anfänglichen Renderings der App. Alternativ kann die App die Daten in einen bereichsbezogenen Dienst im Initialisierungslebenszyklusereignis der Stammkomponente kopieren, um sie in der gesamten App zu verwenden. Weitere Informationen finden Sie unter Zusätzliche serverseitige Sicherheitsszenarien für Blazor in ASP.NET Core.

Ein wichtiger Aspekt der serverseitigen Blazor-Sicherheit ist, dass der Benutzer, der an eine bestimmte Verbindung angefügt ist, möglicherweise irgendwann aktualisiert wird, nachdem die Blazor-Verbindung hergestellt wurde, der IHttpContextAccessor aber nicht aktualisiert wird. Weitere Informationen zum Beheben dieses Problems mit benutzerdefinierten Diensten finden Sie unter Zusätzliche serverseitige Sicherheitsszenarien für ASP.NET Core Blazor.

Freigegebener Zustand

Serverseitige Blazor-Apps befinden sich im Serverspeicher, und mehrere App-Sitzungen werden innerhalb desselben Prozesses gehostet. Blazor startet für jede App-Sitzung eine Verbindung mit einem eigenen Containerbereich für Abhängigkeitsinjektion, sodass bereichsbezogene Dienste pro Blazor-Sitzung eindeutig sind.

Warnung

Es wird nicht empfohlen, dass Apps auf demselben Server sich einen Zustand mithilfe von Singletondiensten teilen, es sei denn, es wird mit äußerster Vorsicht vorgegangen, da dies zu Sicherheitsrisiken führen kann, wie z. B. verbindungsübergreifende Preisgabe des Benutzerzustands.

Sie können zustandsbehaftete Singletondienste in Blazor-Apps verwenden, sofern diese speziell dafür konzipiert sind. Beispielsweise ist die Verwendung eines Singletonspeichercaches akzeptabel, da ein Speichercache einen Schlüssel für den Zugriff auf einen bestimmten Eintrag erfordert. Unter der Annahme, dass Benutzer keine Kontrolle über die Cacheschlüssel besitzen, die mit dem Cache verwendet werden, wird der im Cache gespeicherte Zustand nicht über Verbindungen hinweg weitergegeben.

Eine allgemeine Anleitung zur Zustandsverwaltung finden Sie unter ASP.NET Core Blazor-Zustandsverwaltung.

Clientseitige Blazor-Authentifizierung

In clientseitigen Blazor-Apps können clientseitige Authentifizierungsprüfungen umgangen werden, da der gesamte clientseitige Code von Benutzern geändert werden kann. Dasselbe gilt für alle clientseitigen App-Technologien, darunter JavaScript-SPA-Frameworks und native Apps für jedes Betriebssystem.

Fügen Sie Folgendes hinzu:

Die Verwendung des integrierten oder benutzerdefinierten AuthenticationStateProvider-Diensts zur Verarbeitung der Authentifizierung wird in den folgenden Abschnitten behandelt.

Weitere Informationen finden Sie im Artikel Schützen der Blazor WebAssembly in ASP.NET Core.

AuthenticationStateProvider-Dienst

AuthenticationStateProvider ist der zugrunde liegende Dienst, der von der AuthorizeView-Komponente und kaskadierenden Authentifizierungsdiensten verwendet wird, um den Authentifizierungsstatus für Benutzer*innen abzurufen.

AuthenticationStateProvider ist der zugrunde liegende Dienst, der von der AuthorizeView- und der CascadingAuthenticationState-Komponente verwendet wird, um den Authentifizierungsstatus für einen Benutzer abzurufen.

AuthenticationStateProvider wird in der Regel nicht direkt verwendet. Verwenden Sie die später in diesem Artikel beschriebenen Ansätze AuthorizeView-Komponente oder Task<AuthenticationState>. Der Hauptnachteil bei der direkten Verwendung von AuthenticationStateProvider ist, dass die Komponente nicht automatisch benachrichtigt wird, wenn sich die zugrunde liegenden Daten des Authentifizierungsstatus ändern.

Hinweis

Informationen zum Implementieren eines benutzerdefinierten AuthenticationStateProvider finden Sie unter Schützen von serverseitigen Blazor-Apps in ASP.NET Core.

Der AuthenticationStateProvider-Dienst kann die ClaimsPrincipal-Daten des aktuellen Benutzers bereitstellen, wie im folgenden Beispiel gezeigt.

ClaimsPrincipalData.razor:

@page "/claims-principle-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>ClaimsPrincipal Data</h1>

<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>

<p>@authMessage</p>

@if (claims.Count() > 0)
{
    <ul>
        @foreach (var claim in claims)
        {
            <li>@claim.Type: @claim.Value</li>
        }
    </ul>
}

<p>@surname</p>

@code {
    private string? authMessage;
    private string? surname;
    private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider
            .GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            authMessage = $"{user.Identity.Name} is authenticated.";
            claims = user.Claims;
            surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
        }
        else
        {
            authMessage = "The user is NOT authenticated.";
        }
    }
}

Im vorherigen Beispiel:

  • ClaimsPrincipal.Claims gibt die Benutzeransprüche (claims) zurück, die auf der Benutzeroberfläche angezeigt werden sollen.
  • Die Zeile, die den Nachnamen des Benutzers oder der Benutzerin (surname) abruft, ruft ClaimsPrincipal.FindAll mit einem Prädikat auf, um die Benutzeransprüche zu filtern.
@page "/claims-principle-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>ClaimsPrincipal Data</h1>

<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>

<p>@authMessage</p>

@if (claims.Count() > 0)
{
    <ul>
        @foreach (var claim in claims)
        {
            <li>@claim.Type: @claim.Value</li>
        }
    </ul>
}

<p>@surname</p>

@code {
    private string? authMessage;
    private string? surname;
    private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider
            .GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            authMessage = $"{user.Identity.Name} is authenticated.";
            claims = user.Claims;
            surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
        }
        else
        {
            authMessage = "The user is NOT authenticated.";
        }
    }
}

Wenn user.Identity.IsAuthenticated den Wert true hat und da der Benutzer ein ClaimsPrincipal ist, können Ansprüche aufgezählt und die Mitgliedschaft in Rollen ausgewertet werden.

Weitere Informationen zur Abhängigkeitsinjektion (Dependency Injection, DI) finden Sie unter Abhängigkeitsinjektion in Blazor in ASP.NET Core und Abhängigkeitsinjektion in ASP.NET Core. Informationen zum Implementieren einer benutzerdefinierten AuthenticationStateProvider in serverseitigen Blazor-Apps finden Sie unter Sichere serverseitige ASP.NET Core Blazor-Apps.

Verfügbar machen des Authentifizierungsstatus als kaskadierender Parameter

Wenn für die prozedurale Logik Authentifizierungsstatusdaten erforderlich sind, z. B. bei der Ausführung einer vom Benutzer ausgelösten Aktion, rufen Sie die Authentifizierungsstatusdaten ab, indem Sie einen kaskadierenden Parameter vom Typ Task<AuthenticationState> definieren, wie im folgenden Beispiel gezeigt.

CascadeAuthState.razor:

@page "/cascade-auth-state"

<h1>Cascade Auth State</h1>

<p>@authMessage</p>

@code {
    private string authMessage = "The user is NOT authenticated.";

    [CascadingParameter]
    private Task<AuthenticationState>? authenticationState { get; set; }

    protected override async Task OnInitializedAsync()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user?.Identity is not null && user.Identity.IsAuthenticated)
            {
                authMessage = $"{user.Identity.Name} is authenticated.";
            }
        }
    }
}
@page "/cascade-auth-state"

<h1>Cascade Auth State</h1>

<p>@authMessage</p>

@code {
    private string authMessage = "The user is NOT authenticated.";

    [CascadingParameter]
    private Task<AuthenticationState>? authenticationState { get; set; }

    protected override async Task OnInitializedAsync()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user?.Identity is not null && user.Identity.IsAuthenticated)
            {
                authMessage = $"{user.Identity.Name} is authenticated.";
            }
        }
    }
}

Wenn user.Identity.IsAuthenticated den Wert true hat, können Ansprüche aufgezählt und die Mitgliedschaft in Rollen ausgewertet werden.

Richten Sie den Task<AuthenticationState>Kaskadierungsparameter mithilfe der AuthorizeRouteView und kaskadierender Authentifizierungsstatusdienste ein.

Wenn Sie eine Blazor-App aus einer der Blazor-Projektvorlagen mit aktivierter Authentifizierung erstellen, enthält die App die AuthorizeRouteView und den Aufruf an AddCascadingAuthenticationState, der im folgenden Beispiel gezeigt wird. Eine clientseitige Blazor-App umfasst auch die erforderlichen Dienstregistrierungen. Weitere Informationen werden im Abschnitt Anpassen nicht autorisierter Inhalte mit der Router-Komponente angezeigt.

<Router ...>
    <Found ...>
        <AuthorizeRouteView RouteData="routeData" 
            DefaultLayout="typeof(Layout.MainLayout)" />
        ...
    </Found>
</Router>

Registrieren Sie in der Program-Datei kaskadierende Authentifizierungsstatusdienste:

builder.Services.AddCascadingAuthenticationState();

Richten Sie den Task<AuthenticationState>kaskadierenden Parameter mit den Komponenten AuthorizeRouteView und CascadingAuthenticationState ein.

Wenn Sie eine Blazor-App aus einer der Blazor-Projektvorlagen mit aktivierter Authentifizierung erstellen, enthält die App die Komponenten AuthorizeRouteView und CascadingAuthenticationState, die im folgenden Beispiel gezeigt werden. Eine clientseitige Blazor-App umfasst auch die erforderlichen Dienstregistrierungen. Weitere Informationen werden im Abschnitt Anpassen nicht autorisierter Inhalte mit der Router-Komponente angezeigt.

<CascadingAuthenticationState>
    <Router ...>
        <Found ...>
            <AuthorizeRouteView RouteData="routeData" 
                DefaultLayout="typeof(MainLayout)" />
            ...
        </Found>
    </Router>
</CascadingAuthenticationState>

Hinweis

Seit der Veröffentlichung von ASP.NET Core 5.0.1 und allen weiteren 5.x-Releases enthält die Router-Komponente den PreferExactMatches-Parameter, der auf @true festgelegt ist. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 3.1 zu 5.0.

Fügen Sie in einer clientseitigen Blazor-App Dienste für Optionen und für die Autorisierung zur Program-Datei hinzu:

builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();

In einer serverseitigen Blazor-App sind Dienste für Optionen und die Autorisierung bereits vorhanden. Es sind also keine weiteren Schritte erforderlich.

Autorisierung

Nachdem ein Benutzer authentifiziert wurde, werden Autorisierungsregeln angewendet, um zu steuern, welche Funktionen der Benutzer ausführen kann.

In der Regel wird der Zugriff in Abhängigkeit von folgenden Punkten gewährt oder verweigert:

  • Ein Benutzer ist authentifiziert (angemeldet).
  • Ein Benutzer hat eine Rolle.
  • Ein Benutzer hat einen Anspruch.
  • Ein Richtlinie wird erfüllt.

Jedes dieser Konzepte entspricht dem einer ASP.NET Core MVC- oder Razor Pages-App. Weitere Informationen zu ASP.NET Core-Sicherheit finden Sie im Artikel unter ASP.NET Core-Sicherheit und -IdentitätIdentity.

AuthorizeView-Komponente

Die AuthorizeView-Komponente zeigt selektiv den Inhalt der Benutzeroberfläche an, abhängig davon, ob der Benutzer dazu berechtigt ist. Dieser Ansatz ist nützlich, wenn Sie nur Daten für den Benutzer anzeigen müssen und nicht die Identität des Benutzers in der prozeduralen Logik verwenden müssen.

Die Komponente macht eine Variable context vom Typ AuthenticationState (@context in der Razor-Syntax) verfügbar, mit der Sie auf Informationen über den angemeldeten Benutzer zugreifen können:

<AuthorizeView>
    <p>Hello, @context.User.Identity?.Name!</p>
</AuthorizeView>

Mit einer Kombination aus den Parametern Authorized und NotAuthorized können Sie auch andere Inhalte für die Anzeige bereitstellen, wenn der Benutzer nicht autorisiert ist:

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
        <p><button @onclick="SecureMethod">Authorized Only Button</button></p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
    private void SecureMethod() { ... }
}

Ein Standardereignishandler für ein autorisiertes Element, zum Beispiel die SecureMethod-Methode für das <button>-Element im vorangegangenen Beispiel, kann nur von einem autorisierten Benutzer aufgerufen werden.

Razor Komponenten von Blazor Web Apps zeigen niemals <NotAuthorized>-Inhalte an, wenn die Autorisierung während des statischen serverseitigen Renderings (statischer SSR) serverseitig fehlschlägt. Die serverseitige ASP.NET Core-Pipeline verarbeitet die Autorisierung auf dem Server. Verwenden Sie serverseitige Techniken, um nicht autorisierte Anforderungen zu verarbeiten. Weitere Informationen finden Sie unter ASP.NET Core Blazor-Rendermodi.

Warnung

Clientseitiges Markup und Methoden, die einer AuthorizeView zugeordnet sind, werden nur in der gerenderten Benutzeroberfläche in clientseitigen Blazor-Apps vor Ansicht und Ausführung geschützt. Um autorisierte Inhalte und sichere Methoden für clientseitige Blazor zu schützen, werden die Inhalte in der Regel durch einen sicheren, autorisierten Web-API-Aufruf einer Server-API bereitgestellt und nie in der App gespeichert. Weitere Informationen finden Sie unter Aufrufen einer Web-API aus einer ASP.NET Core-Blazor-App und unter Zusätzliche Sicherheitsszenarios für ASP.NET Core Blazor WebAssembly.

Der Inhalt von Authorized und NotAuthorized kann beliebige Elemente beinhalten, wie beispielsweise andere interaktive Komponenten.

Autorisierungsbedingungen, wie Rollen oder Richtlinien, die Benutzeroberflächenoptionen oder den Zugriff steuern, werden im Abschnitt Autorisierung behandelt.

Wenn keine Autorisierungsbedingungen angegeben sind, verwendet AuthorizeView eine Standardrichtlinie:

  • Authentifizierte (angemeldete) Benutzer werden autorisiert.
  • Nicht authentifizierte (abgemeldete) Benutzer werden nicht autorisiert.

Die Komponente AuthorizeView kann in der Komponente NavMenu (Shared/NavMenu.razor) verwendet werden, um eine NavLink-Komponente (NavLink) anzuzeigen. Beachten Sie jedoch, dass bei diesem Ansatz nur das Listenelement aus der gerenderten Ausgabe entfernt wird. Benutzer werden nicht daran gehindert, zur Komponente zu navigieren. Implementieren Sie die Autorisierung separat in der Zielkomponente.

Rollenbasierte und richtlinienbasierte Autorisierung

Die AuthorizeView-Komponente unterstützt die rollenbasierte oder die richtlinienbasierte Autorisierung.

Verwenden Sie für die rollenbasierte Autorisierung den Roles-Parameter. Im folgenden Beispiel muss der Benutzer über einen Rollenanspruch für die Rolle Admin oder Superuser verfügen:

<AuthorizeView Roles="Admin, Superuser">
    <p>You have an 'Admin' or 'Superuser' role claim.</p>
</AuthorizeView>

Um zu verlangen, dass ein Benutzer sowohl über den Rollenanspruch Admin als auch über den Rollenanspruch Superuser verfügt, schachteln Sie AuthorizeView-Komponenten:

<AuthorizeView Roles="Admin">
    <p>User: @context.User</p>
    <p>You have the 'Admin' role claim.</p>
    <AuthorizeView Roles="Superuser" Context="innerContext">
        <p>User: @innerContext.User</p>
        <p>You have both 'Admin' and 'Superuser' role claims.</p>
    </AuthorizeView>
</AuthorizeView>

Der vorangehende Code richtet einen Context für die innere AuthorizeView-Komponente ein, um einen AuthenticationState-Kontextkonflikt zu verhindern. Auf den AuthenticationState-Kontext wird im äußeren AuthorizeView mit dem Standardansatz für den Zugriff auf den Kontext zugegriffen (@context.User). Auf den Kontext wird im inneren AuthorizeView mit dem benannten innerContext-Kontext (@innerContext.User) zugegriffen.

Weitere Informationen, einschließlich Konfigurationsanleitungen, finden Sie unter Rollenbasierte Autorisierung in ASP.NET Core.

Verwenden Sie für die richtlinienbasierte Autorisierung den Policy-Parameter mit einer einzelnen Richtlinie:

<AuthorizeView Policy="Over21">
    <p>You satisfy the 'Over21' policy.</p>
</AuthorizeView>

Für den Fall, dass der Benutzer eine von mehreren Richtlinien erfüllen muss, erstellen Sie eine Richtlinie, die bestätigt, dass der Benutzer andere Richtlinien erfüllt.

Für den Fall, dass der Benutzer mehrere Richtlinien gleichzeitig erfüllen muss, setzen Sie einen der folgenden Ansätze um:

  • Erstellen Sie eine Richtlinie für AuthorizeView, die bestätigt, dass der Benutzer mehrere andere Richtlinien erfüllt.

  • Schachteln Sie die Richtlinien in mehreren AuthorizeView-Komponenten:

    <AuthorizeView Policy="Over21">
        <AuthorizeView Policy="LivesInCalifornia">
            <p>You satisfy the 'Over21' and 'LivesInCalifornia' policies.</p>
        </AuthorizeView>
    </AuthorizeView>
    

Die anspruchsbasierte Autorisierung ist ein Sonderfall der richtlinienbasierten Autorisierung. Beispielsweise können Sie eine Richtlinie definieren, die vom Benutzer einen bestimmten Anspruch erfordert. Weitere Informationen finden Sie unter Richtlinienbasierte Autorisierung in ASP.NET Core.

Wenn weder Roles noch Policy angegeben wird, verwendet AuthorizeView die Standardrichtlinie:

  • Authentifizierte (angemeldete) Benutzer werden autorisiert.
  • Nicht authentifizierte (abgemeldete) Benutzer werden nicht autorisiert.

Da bei .NET-Zeichenfolgenvergleichen standardmäßig die Groß-/Kleinschreibung beachtet wird, wird beim Abgleich von Rollen- und Richtliniennamen auch die Groß-/Kleinschreibung beachtet. Beispielsweise wird Admin (mit Großbuchstabe A) nicht als dieselbe Rolle wie admin (mit Kleinbuchstabe a) behandelt.

Die Pascal-Schreibweise wird in der Regel für Rollen- und Richtliniennamen (z. B. BillingAdministrator) verwendet, aber die Verwendung der Pascal-Schreibweise ist keine strenge Anforderung. Unterschiedliche Groß-/Kleinschreibungen wie Camel Case, Kebab Case und Snake Case sind zulässig. Die Verwendung von Leerzeichen in Rollen- und Richtliniennamen ist ungewöhnlich, wird aber vom Framework zugelassen. Beispielsweise ist billing administrator ein ungewöhnliches Format für Rollen- oder Richtliniennamen in .NET-Apps. Dennoch ist dies ein gültiger Rollen- oder Richtlinienname.

Während der asynchronen Authentifizierung angezeigter Inhalt

Bei Blazor kann der Authentifizierungsstatus asynchron bestimmt werden. Das primäre Szenario für diesen Ansatz sind clientseitige Blazor-Apps, die eine Anforderung zur Authentifizierung an einen externen Endpunkt stellen.

Während der Authentifizierung zeigt AuthorizeView standardmäßig keine Inhalte an. Um Inhalte während der Authentifizierung anzuzeigen, weisen Sie dem Authorizing Parameter Inhalte zu:

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <Authorizing>
        <p>You can only see this content while authentication is in progress.</p>
    </Authorizing>
</AuthorizeView>

Dieser Ansatz gilt in der Regel nicht für serverseitige Blazor-Apps. Serverseitige Blazor-Apps kennen den Authentifizierungsstatus, sobald der Status hergestellt ist. Authorizing-Inhalte können zwar in der AuthorizeView-Komponente einer App bereitgestellt werden, der Inhalt wird aber nie angezeigt.

[Authorize]-Attribut

Das [Authorize]-Attribut ist in Razor-Komponenten verfügbar:

@page "/"
@attribute [Authorize]

You can only see this if you're signed in.

Wichtig

Verwenden Sie nur [Authorize] für @page-Komponenten, die über den Blazor-Router angesteuert werden. Die Autorisierung wird nur als Aspekt des Routings und nicht für untergeordnete Komponenten durchgeführt, die innerhalb einer Seite gerendert werden. Um die Anzeige von bestimmten Teilen innerhalb einer Seite zu autorisieren, verwenden Sie stattdessen AuthorizeView.

Das [Authorize]-Attribut unterstützt auch die rollenbasierte oder die richtlinienbasierte Autorisierung. Verwenden Sie für die rollenbasierte Autorisierung den Roles-Parameter:

@page "/"
@attribute [Authorize(Roles = "Admin, Superuser")]

<p>You can only see this if you're in the 'Admin' or 'Superuser' role.</p>

Verwenden Sie für die richtlinienbasierte Autorisierung den Policy-Parameter:

@page "/"
@attribute [Authorize(Policy = "Over21")]

<p>You can only see this if you satisfy the 'Over21' policy.</p>

Wenn weder Roles noch Policy angegeben wird, verwendet [Authorize] die Standardrichtlinie:

  • Authentifizierte (angemeldete) Benutzer werden autorisiert.
  • Nicht authentifizierte (abgemeldete) Benutzer werden nicht autorisiert.

Wenn der Benutzer nicht autorisiert ist und die App keine Anpassung nicht autorisierter Inhalte mit der Router-Komponente vornimmt, zeigt das Framework automatisch die folgende Fallbackmeldung an:

Not authorized.

Ressourcenautorisierung

Wenn Sie Benutzer*innen für Ressourcen autorisieren möchten, übergeben Sie die Routendaten der Anforderung an den Resource-Parameter von AuthorizeRouteView.

Im Router.Found-Inhalt für eine angeforderte Route:

<AuthorizeRouteView Resource="routeData" RouteData="routeData" 
    DefaultLayout="typeof(MainLayout)" />

Weitere Informationen dazu, wie Autorisierungsstatusdaten übergeben und in der prozeduralen Logik verwendet werden, finden Sie im Abschnitt Verfügbar machen des Authentifizierungsstatus als kaskadierender Parameter.

Wenn AuthorizeRouteView die Routendaten für die Ressource empfängt, haben Autorisierungsrichtlinien Zugriff auf RouteData.PageType und RouteData.RouteValues, die es benutzerdefinierter Logik ermöglichen, Autorisierungsentscheidungen zu treffen.

Im folgenden Beispiel wird in AuthorizationOptions eine EditUser-Richtlinie für die Konfiguration des Autorisierungsdiensts der App (AddAuthorizationCore) mit der folgenden Logik erstellt:

  • Ermitteln Sie, ob ein Routenwert mit dem Schlüssel id vorhanden ist. Wenn der Schlüssel vorhanden ist, wird der Routenwert in value gespeichert.
  • Speichern Sie value in einer Variablen mit dem Namen id als Zeichenfolge, oder legen Sie einen leeren Zeichenfolgenwert fest (string.Empty).
  • Bestätigen Sie, dass die Richtlinie erfüllt ist (geben Sie true zurück), wenn id keine leere Zeichenfolge ist und der Wert der Zeichenfolge mit EMP beginnt. Andernfalls bestätigen Sie, dass die Richtlinie fehlschlägt (geben Sie false zurück).

In der Program-Datei:

  • Fügen Sie für Microsoft.AspNetCore.Components und System.Linq Namespaces hinzu:

    using Microsoft.AspNetCore.Components;
    using System.Linq;
    
  • Fügen Sie die Richtlinie hinzu:

    options.AddPolicy("EditUser", policy =>
        policy.RequireAssertion(context =>
        {
            if (context.Resource is RouteData rd)
            {
                var routeValue = rd.RouteValues.TryGetValue("id", out var value);
                var id = Convert.ToString(value, 
                    System.Globalization.CultureInfo.InvariantCulture) ?? string.Empty;
    
                if (!string.IsNullOrEmpty(id))
                {
                    return id.StartsWith("EMP", StringComparison.InvariantCulture);
                }
            }
    
            return false;
        })
    );
    

Beim obigen Beispiel handelt es sich um eine stark vereinfachte Autorisierungsrichtlinie, die lediglich verwendet wird, um das Konzept anhand eines funktionierenden Beispiels zu veranschaulichen. Weitere Informationen zum Erstellen und Konfigurieren von Autorisierungsrichtlinien finden Sie unter Richtlinienbasierte Autorisierung in ASP.NET Core.

In der folgenden EditUser-Komponente verfügt die Ressource unter /users/{id}/edit über einen Routenparameter für den Bezeichner des Benutzers ({id}). Die Komponente verwendet die vorstehende EditUser-Autorisierungsrichtlinie, um zu ermitteln, ob der Routenwert für id mit EMP beginnt. Wenn id mit EMP beginnt, ist die Richtlinie erfolgreich, und der Zugriff auf die Komponente ist autorisiert. Wenn id mit einem anderen Wert als EMP beginnt, oder wenn id eine leere Zeichenfolge ist, schlägt die Richtlinie fehl, und die Komponente wird nicht geladen.

EditUser.razor:

@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]

<h1>Edit User</h1>

<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>

@code {
    [Parameter]
    public string? Id { get; set; }
}
@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]

<h1>Edit User</h1>

<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>

@code {
    [Parameter]
    public string? Id { get; set; }
}

Anpassen von unautorisierten Inhalten mit der Router-Komponente

Gemeinsam mit der AuthorizeRouteView-Komponente ermöglicht die Router-Komponente der App, benutzerdefinierten Inhalt anzugeben, wenn:

  • Der Benutzer eine [Authorize]-Bedingung nicht erfüllt, die für die Komponente angewendet wird. Das Markup des <NotAuthorized>-Elements wird angezeigt. Das [Authorize]-Attribut wird im Abschnitt [Authorize]-Attribut behandelt.
  • Asynchrone Autorisierung wird ausgeführt. Dies bedeutet in der Regel, dass der Benutzer authentifiziert wird. Das Markup des <Authorizing>-Elements wird angezeigt.

Wichtig

Blazor Routerfeatures, die <NotAuthorized>- und <NotFound>-Inhalte anzeigen während des statischen serverseitigen Renderings (statischer SSR) nicht betriebsbereit sind, da die Anforderungsverarbeitung vollständig von ASP.NET Core Middleware-Pipelineanforderungsverarbeitung verarbeitet wird und Razor Komponenten nicht für nicht autorisierte oder fehlerhafte Anforderungen gerendert werden. Verwenden Sie serverseitige Techniken, um nicht autorisierte und fehlerhafte Anforderungen während statischer SSR zu verarbeiten. Weitere Informationen finden Sie unter ASP.NET Core Blazor-Rendermodi.

<Router ...>
    <Found ...>
        <AuthorizeRouteView ...>
            <NotAuthorized>
                ...
            </NotAuthorized>
            <Authorizing>
                ...
            </Authorizing>
        </AuthorizeRouteView>
    </Found>
</Router>

Der Inhalt von Authorized und NotAuthorized kann beliebige Elemente beinhalten, wie beispielsweise andere interaktive Komponenten.

Hinweis

Im Vorherigen ist die Registrierung von Authentifizierungsstatusdiensten in der Program-Datei der App erforderlich:

builder.Services.AddCascadingAuthenticationState();
<CascadingAuthenticationState>
    <Router ...>
        <Found ...>
            <AuthorizeRouteView ...>
                <NotAuthorized>
                    ...
                </NotAuthorized>
                <Authorizing>
                    ...
                </Authorizing>
            </AuthorizeRouteView>
        </Found>
    </Router>
</CascadingAuthenticationState>

Der Inhalt von NotFound, Authorized und NotAuthorized kann beliebige Elemente beinhalten, wie beispielsweise andere interaktive Komponenten.

Wenn der Inhalt NotAuthorized nicht angegeben ist, verwendet AuthorizeRouteView die folgende alternative Meldung:

Not authorized.

Eine App, die aus der Blazor WebAssembly-Projektvorlage mit aktivierter Authentifizierung erstellt wird, enthält eine RedirectToLogin-Komponente, die im <NotAuthorized>-Inhalt der Router-Komponente positioniert wird. Wenn ein Benutzer nicht authentifiziert ist (context.User.Identity?.IsAuthenticated != true), leitet die RedirectToLogin-Komponente den Browser zur Authentifizierung an den authentication/login-Endpunkt um. Der Benutzer wird nach der Authentifizierung beim Identitätsanbieter an die angeforderte URL zurückgeleitet.

Prozedurale Logik

Wenn die App zur Überprüfung von Autorisierungsregeln im Rahmen der prozeduralen Logik benötigt wird, verwenden Sie einen kaskadierten Parameter vom Typ Task<AuthenticationState>, um das ClaimsPrincipal des Benutzers abzurufen. Task<AuthenticationState> kann zum Auswerten von Richtlinien mit anderen Diensten kombiniert werden, wie z. B. IAuthorizationService.

Im folgenden Beispiel:

  • user.Identity.IsAuthenticated führt Code für authentifizierte (angemeldete) Benutzer aus.
  • user.IsInRole("admin") führt Code für Benutzer mit der Rolle „Admin“ aus.
  • (await AuthorizationService.AuthorizeAsync(user, "content-editor")).Succeeded führt Code für Benutzer aus, die die Richtlinie „content-editor“ erfüllen.

Eine serverseitige Blazor-App enthält standardmäßig die entsprechenden Namespaces, wenn sie aus der Projektvorlage erstellt wird. Überprüfen Sie in einer clientseitigen Blazor-App, ob die Namespaces Microsoft.AspNetCore.Authorization und Microsoft.AspNetCore.Components.Authorization entweder in der Komponente oder in der Datei _Imports.razor der App vorhanden sind:

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization

ProceduralLogic.razor:

@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService

<h1>Procedural Logic Example</h1>

<button @onclick="@DoSomething">Do something important</button>

@code {
    [CascadingParameter]
    private Task<AuthenticationState>? authenticationState { get; set; }

    private async Task DoSomething()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user is not null)
            {
                if (user.Identity is not null && user.Identity.IsAuthenticated)
                {
                    // ...
                }

                if (user.IsInRole("Admin"))
                {
                    // ...
                }

                if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
                    .Succeeded)
                {
                    // ...
                }
            }
        }
    }
}
@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService

<h1>Procedural Logic Example</h1>

<button @onclick="@DoSomething">Do something important</button>

@code {
    [CascadingParameter]
    private Task<AuthenticationState>? authenticationState { get; set; }

    private async Task DoSomething()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user is not null)
            {
                if (user.Identity is not null && user.Identity.IsAuthenticated)
                {
                    // ...
                }

                if (user.IsInRole("Admin"))
                {
                    // ...
                }

                if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
                    .Succeeded)
                {
                    // ...
                }
            }
        }
    }
}

Fehlerbehandlung

Häufige Fehler:

  • Die Autorisierung erfordert einen kaskadierenden Parameter vom Typ Task<AuthenticationState>. Verwenden Sie CascadingAuthenticationState, um diesen bereitzustellen.

  • Für authenticationStateTask wird ein null -Wert empfangen.

Wahrscheinlich wurde das Projekt nicht mit einer serverseitigen Blazor-Vorlage mit aktivierter Authentifizierung erstellt.

Umschließen Sie in .NET 7 oder früher einen Teil der Benutzeroberflächenstruktur mit einem <CascadingAuthenticationState>, zum Beispiel den Blazor-Router:

<CascadingAuthenticationState>
    <Router ...>
        ...
    </Router>
</CascadingAuthenticationState>

Verwenden Sie in .NET 8 oder höher nicht die CascadingAuthenticationState-Komponente:

- <CascadingAuthenticationState>
      <Router ...>
          ...
      </Router>
- </CascadingAuthenticationState>

Fügen Sie stattdessen der Dienstauflistung in der Program-Datei kaskadierende Authentifizierungszustandsdienste hinzu:

builder.Services.AddCascadingAuthenticationState();

Die CascadingAuthenticationState-Komponente (.NET 7 oder früher) oder Dienste, die von AddCascadingAuthenticationState (.NET 8 oder höher) bereitgestellt werden, stellt den >Task<AuthenticationState-Kaskadierungsparameter bereit, der wiederum vom zugrunde liegenden AuthenticationStateProvider-Abhängigkeitserfassungsdienst empfangen wird.

Personenbezogene Informationen (Personally Identifiable Information, PII)

Microsoft verwendet die DSGVO-Definition für „personenbezogene Daten“ (DSGVO 4.1), wenn dokumentation informationen zu personenbezogenen Informationen (Personally Identifiable Information, PII) erläutert.

PII bezieht sich auf alle Informationen, die sich auf eine identifizierte oder identifizierbare natürliche Person beziehen. Eine identifizierbare natürliche Person ist eine Person, die direkt oder indirekt mit einer der folgenden Identifiziert werden kann:

  • Name
  • Identifikationsnummer
  • Standortkoordinaten
  • Onlinebezeichner
  • Andere spezifische Faktoren
    • Physisch
    • Physiologisch
    • Genetisch
    • Mental (psychologisch)
    • Wirtschaftlichen
    • Kultur
    • Soziale Identität

Zusätzliche Ressourcen