ASP.NET Core-autentiseringstillstånd Blazor

Anmärkning

Det här är inte den senaste versionen av den här artikeln. Den aktuella versionen finns i .NET 10-versionen av den här artikeln.

Varning

Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i supportpolicyn för .NET och .NET Core. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln .

Den här artikeln beskriver hur du skapar en anpassad autentiseringstillståndsprovider och tar emot meddelanden om ändring av användarautentiseringstillstånd i kod.

De allmänna metoderna för appar på serversidan och klientsidan Blazor är liknande men skiljer sig åt i deras exakta implementeringar, så den här artikeln pivoteras mellan appar på serversidan Blazor och appar på klientsidan Blazor . Använd pivotväljaren överst i artikeln för att ändra artikelns pivot så att den matchar den typ av Blazor projekt som du arbetar med:

  • Appar på serversidan Blazor (Server pivot): Blazor Server för .NET 7 eller tidigare och serverprojektet för en Blazor Web App för .NET 8 eller senare.
  • Applikationer på klientsidan Blazor (Blazor WebAssembly pivot): Blazor WebAssembly för alla versioner av .NET eller projektet .Client av en Blazor Web App för .NET 8 eller senare.

Abstrakt AuthenticationStateProvider klass

Ramverket Blazor innehåller en abstrakt AuthenticationStateProvider klass för att ge information om den aktuella användarens autentiseringstillstånd med följande medlemmar:

Definiera en anpassad AuthenticationStateProvider

Appen måste referera till Microsoft.AspNetCore.Components.Authorization NuGet-paketet, som tillhandahåller stöd för autentisering och auktorisering för Blazor appar.

Anmärkning

Vägledning om hur du lägger till paket i .NET-appar finns i artiklarna under Installera och hantera paket i arbetsflödet för paketförbrukning (NuGet-dokumentation). Bekräfta rätt paketversioner på NuGet.org.

Konfigurera följande tjänster för autentisering, auktorisering och sammanhängande autentiseringstillstånd i Program filen.

När du skapar en Blazor app från en av Blazor projektmallarna med autentisering aktiverat, förkonfigureras appen med följande tjänstregistreringar, vilket innefattar att exponera autentiseringstillståndet som en sammanhängande parameter. Mer information finns i ASP.NET Core-autentisering Blazor och -auktorisering med ytterligare information som visas i artikeln Anpassa obehörigt innehåll med komponentavsnittetRouter.

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorization();
builder.Services.AddCascadingAuthenticationState();

Konfigurera autentiserings- och auktoriseringstjänster i Program filen.

När du skapar en Blazor app från en av Blazor projektmallarna med autentisering aktiverat innehåller appen följande tjänstregistrering.

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorization();

Konfigurera autentiserings- och auktoriseringstjänster i Startup.ConfigureServicesStartup.cs.

När du skapar en Blazor app från en av Blazor projektmallarna med autentisering aktiverat innehåller appen följande tjänstregistrering.

using Microsoft.AspNetCore.Components.Authorization;

...

services.AddAuthorization();

I Blazor WebAssembly appar (alla .NET-versioner) eller .Client projektet för en Blazor Web App (.NET 8 eller senare) konfigurerar du autentiserings-, auktoriserings- och sammanhängande autentiseringstillståndstjänster i Program filen.

När du skapar en Blazor app från en av Blazor projektmallarna med autentisering aktiverat, förkonfigureras appen med följande tjänstregistreringar, vilket innefattar att exponera autentiseringstillståndet som en sammanhängande parameter. Mer information finns i ASP.NET Core-autentisering Blazor och -auktorisering med ytterligare information som visas i artikeln Anpassa obehörigt innehåll med komponentavsnittetRouter.

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();

Konfigurera autentiserings- och auktoriseringstjänster i Program filen.

När du skapar en Blazor app från en av Blazor projektmallarna med autentisering aktiverat innehåller appen följande tjänstregistrering.

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorizationCore();

Underklass AuthenticationStateProvider och åsidosättning GetAuthenticationStateAsync för att skapa användarens autentiseringstillstånd. I följande exempel autentiseras alla användare med användarnamnet mrfibuli.

CustomAuthStateProvider.cs:

using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;

public class CustomAuthStateProvider : AuthenticationStateProvider
{
    public override Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        var identity = new ClaimsIdentity(
        [
            new Claim(ClaimTypes.Name, "mrfibuli"),
        ], "Custom Authentication");

        var user = new ClaimsPrincipal(identity);

        return Task.FromResult(new AuthenticationState(user));
    }
}

Anmärkning

Föregående kod som skapar en ny ClaimsIdentity använder förenklad insamlingsinitiering som introducerades med C# 12 (.NET 8). Mer information finns i Samlingsuttryck – C#-språkreferens.

Tjänsten CustomAuthStateProvider är registrerad i Program filen. Registrera tjänsten scoped med AddScoped:

builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

I en Blazor Server-app registrerar du tjänsten scoped med AddScopedefter att du har anropat AddServerSideBlazor:

builder.Services.AddServerSideBlazor();

builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

I en Blazor Server-app registrerar du tjänsten scoped med AddScopedefter att du har anropat AddServerSideBlazor:

services.AddServerSideBlazor();

services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

Tjänsten CustomAuthStateProvider är registrerad i Program filen. Registrera tjänsten singleton med AddSingleton:

builder.Services.AddSingleton<AuthenticationStateProvider, CustomAuthStateProvider>();

Om den inte finns lägger du till en @using instruktion i _Imports.razor filen för att göra Microsoft.AspNetCore.Components.Authorization namnområdet tillgängligt mellan komponenter:

@using Microsoft.AspNetCore.Components.Authorization;

Bekräfta eller ändra vägvisningskomponenten till en AuthorizeRouteView i komponentdefinitionen Router . Platsen för komponenten Router varierar beroende på apptyp. Använd sökfunktionen för att hitta komponenten om du inte känner till dess plats i projektet.

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

Anmärkning

När du skapar en Blazor app från en av Blazor projektmallarna med autentisering aktiverat inkluderar appen komponenten AuthorizeRouteView . Mer information finns i ASP.NET Core-autentisering Blazor och -auktorisering med ytterligare information som visas i artikeln Anpassa obehörigt innehåll med komponentavsnittetRouter.

Var komponenten Router finns:

Platsen för komponenten Router varierar beroende på apptyp. Använd sökfunktionen för att hitta komponenten om du inte känner till dess plats i projektet.

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

Anmärkning

När du skapar en Blazor app från en av Blazor projektmallarna med autentisering aktiverat innehåller appen komponenterna AuthorizeRouteView och CascadingAuthenticationState . Mer information finns i ASP.NET Core-autentisering Blazor och -auktorisering med ytterligare information som visas i artikeln Anpassa obehörigt innehåll med komponentavsnittetRouter.

Följande exempelkomponent AuthorizeView visar den autentiserade användarens namn:

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

Information om hur du använder AuthorizeViewfinns i ASP.NET Core-autentisering Blazor och -auktorisering.

Meddelanden om ändring av autentiseringstillstånd

En anpassad AuthenticationStateProvider kan anropa NotifyAuthenticationStateChanged i basklassen AuthenticationStateProvider för att meddela användarna om att autentiseringstillståndet ändras till att återskapas.

Följande exempel baseras på implementering av en anpassad AuthenticationStateProvider genom att följa riktlinjerna i avsnittet Implementera en anpassad AuthenticationStateProvider tidigare i den här artikeln. Om du redan har följt riktlinjerna i det avsnittet ersätter följande CustomAuthStateProvider den som visas i avsnittet.

Följande CustomAuthStateProvider implementering exponerar en anpassad metod, , AuthenticateUserför att logga in en användare och meddela användarna om ändringen av autentiseringstillståndet.

CustomAuthStateProvider.cs:

using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;

public class CustomAuthStateProvider : AuthenticationStateProvider
{
    public override Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        var identity = new ClaimsIdentity();
        var user = new ClaimsPrincipal(identity);

        return Task.FromResult(new AuthenticationState(user));
    }

    public void AuthenticateUser(string userIdentifier)
    {
        var identity = new ClaimsIdentity(
        [
            new Claim(ClaimTypes.Name, userIdentifier),
        ], "Custom Authentication");

        var user = new ClaimsPrincipal(identity);

        NotifyAuthenticationStateChanged(
            Task.FromResult(new AuthenticationState(user)));
    }
}

Anmärkning

Föregående kod som skapar en ny ClaimsIdentity använder förenklad insamlingsinitiering som introducerades med C# 12 (.NET 8). Mer information finns i Samlingsuttryck – C#-språkreferens.

I en komponent:

@inject AuthenticationStateProvider AuthenticationStateProvider

<input @bind="userIdentifier" />
<button @onclick="SignIn">Sign in</button>

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
    public string userIdentifier = string.Empty;

    private void SignIn()
    {
        ((CustomAuthStateProvider)AuthenticationStateProvider)
            .AuthenticateUser(userIdentifier);
    }
}

Föregående metod kan förbättras för att utlösa meddelanden om ändringar av autentiseringstillstånd via en anpassad tjänst. Följande CustomAuthenticationService-klass hanterar den aktuella användarens claims-principal i ett bakgrundsfält (currentUser), med en händelse (UserChanged) som autentiseringsstatusprovidern kan prenumerera på, där händelsen anropar NotifyAuthenticationStateChanged. Med den ytterligare konfigurationen senare i det här avsnittet kan CustomAuthenticationService injiceras i en komponent med logik som ställer in CurrentUser för att utlösa UserChanged-händelsen.

CustomAuthenticationService.cs:

using System.Security.Claims;

public class CustomAuthenticationService
{
    public event Action<ClaimsPrincipal>? UserChanged;
    private ClaimsPrincipal? currentUser;

    public ClaimsPrincipal CurrentUser
    {
        get { return currentUser ?? new(); }
        set
        {
            currentUser = value;

            if (UserChanged is not null)
            {
                UserChanged(currentUser);
            }
        }
    }
}

Program I filen registrerar du CustomAuthenticationService i containern för beroendeinmatning:

builder.Services.AddScoped<CustomAuthenticationService>();

I Startup.ConfigureServices och Startup.cs registrerar du CustomAuthenticationService i containern för beroendeinjektion.

services.AddScoped<CustomAuthenticationService>();

Program I filen registrerar du CustomAuthenticationService i containern för beroendeinmatning:

builder.Services.AddSingleton<CustomAuthenticationService>();

Följande CustomAuthStateProvider prenumererar på händelsen CustomAuthenticationService.UserChanged. Metoden GetAuthenticationStateAsync returnerar användarens autentiseringstillstånd. Inledningsvis baseras autentiseringstillståndet på värdet för CustomAuthenticationService.CurrentUser. När användaren ändras skapas ett nytt autentiseringstillstånd för den nya användaren (new AuthenticationState(newUser)) för anrop till GetAuthenticationStateAsync:

using Microsoft.AspNetCore.Components.Authorization;

public class CustomAuthStateProvider : AuthenticationStateProvider
{
    private AuthenticationState authenticationState;

    public CustomAuthStateProvider(CustomAuthenticationService service)
    {
        authenticationState = new AuthenticationState(service.CurrentUser);

        service.UserChanged += (newUser) =>
        {
            authenticationState = new AuthenticationState(newUser);
            NotifyAuthenticationStateChanged(Task.FromResult(authenticationState));
        };
    }

    public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
        Task.FromResult(authenticationState);
}

Följande komponents SignIn metod skapar ett anspråkshuvudnamn för användarens identifierare som ska anges på CustomAuthenticationService.CurrentUser:

@using System.Security.Claims
@inject CustomAuthenticationService AuthService

<input @bind="userIdentifier" />
<button @onclick="SignIn">Sign in</button>

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
    public string userIdentifier = string.Empty;

    private void SignIn()
    {
        var currentUser = AuthService.CurrentUser;

        var identity = new ClaimsIdentity(
            [
                new Claim(ClaimTypes.Name, userIdentifier),
            ],
            "Custom Authentication");

        var newUser = new ClaimsPrincipal(identity);

        AuthService.CurrentUser = newUser;
    }
}

Anmärkning

Föregående kod som skapar en ny ClaimsIdentity använder förenklad insamlingsinitiering som introducerades med C# 12 (.NET 8). Mer information finns i Samlingsuttryck – C#-språkreferens.

Ytterligare resurser