共用方式為


ASP.NET Core Blazor 驗證狀態

注意

這不是這篇文章的最新版本。 如需目前版本,請參閱本文的 .NET 8 版本

警告

不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支援原則。 如需目前版本,請參閱本文的 .NET 8 版本

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

如需目前版本,請參閱本文的 .NET 8 版本

本文說明如何建立自訂 驗證狀態提供者 ,並在程式碼中接收使用者驗證狀態變更通知。

伺服器端和用戶端 Blazor 應用程式採用的一般方法很類似,但其具體實作有所不同,因此本文主要在伺服器端 Blazor 應用程式和用戶端 Blazor 應用程式進行分析。 使用文章頂端的樞紐選取器來變更文章的樞紐,以符合您正在使用的 Blazor 專案類型:

  • 伺服器端 Blazor 應用程式(Server 樞紐): Blazor Server 適用於 .NET 7 或更早版本,以及適用於 .NET 8 或更新版本的 Blazor Web App 伺服器專案。
  • 用戶端 Blazor 應用程式(Blazor WebAssembly 樞紐): Blazor WebAssembly 適用於 .NET 的所有版本,或 Blazor Web App 適用於 .NET 8 或更新版本的 .Client 專案。

抽象 AuthenticationStateProvider 類別

架構 Blazor 包含抽象 AuthenticationStateProvider 類別,透過下列成員提供有關目前使用者驗證狀態的相關資訊:

實作自訂 AuthenticationStateProvider

應用程式必須參考 Microsoft.AspNetCore.Components.Authorization NuGet 套件,它為 Blazor 應用程式提供驗證和授權支援。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。

Program 檔案中設定下列驗證、授權和串聯驗證狀態服務。

當您從其中一個已啟用驗證的 Blazor 專案範本建立 Blazor 應用程式時,該應用程式會預先設定為下列服務註冊,其中包括將驗證狀態公開為串聯參數。 如需詳細資訊,請參閱 ASP.NET Core Blazor 驗證與授權,以及本文的使用 Router 元件自訂未經授權的內容一節中呈現的其他資訊。

using Microsoft.AspNetCore.Components.Authorization;

...

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

Program 檔案中設定驗證和授權服務。

當您從其中一個已啟用驗證的 Blazor 專案範本建立 Blazor 應用程式時,此應用程式包含 以下服務註冊。

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorization();

Startup.csStartup.ConfigureServices 設定驗證與授權服務。

當您從其中一個已啟用驗證的 Blazor 專案範本建立 Blazor 應用程式時,此應用程式包含 以下服務註冊。

using Microsoft.AspNetCore.Components.Authorization;

...

services.AddAuthorization();

在 Blazor WebAssembly 應用程式(所有 .NET 版本)或 Blazor Web App (.NET 8 或更新版本) 的 .Client 專案,在 Program 檔案中設定驗證、授權和串聯驗證狀態服務。

當您從其中一個已啟用驗證的 Blazor 專案範本建立 Blazor 應用程式時,該應用程式會預先設定為下列服務註冊,其中包括將驗證狀態公開為串聯參數。 如需詳細資訊,請參閱 ASP.NET Core Blazor 驗證與授權,以及本文的使用 Router 元件自訂未經授權的內容一節中呈現的其他資訊。

using Microsoft.AspNetCore.Components.Authorization;

...

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

Program 檔案中設定驗證和授權服務。

當您從其中一個已啟用驗證的 Blazor 專案範本建立 Blazor 應用程式時,此應用程式包含 以下服務註冊。

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorizationCore();

子類別 AuthenticationStateProvider 和覆寫 GetAuthenticationStateAsync 以建立使用者的驗證狀態。 在下列範例中,所有使用者都會以使用者名稱 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));
    }
}

注意

上述建立新 ClaimsIdentity 的程式碼使用 C# 12 (.NET 8) 引進的簡易集合初始化。 如需詳細資訊,請參閱 集合表達 - C# 語言參考

CustomAuthStateProvider 服務會在 Program 檔案中註冊: 使用 AddScoped註冊服務 範圍

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

在 Blazor Server 應用程式中,使用 AddScoped 呼叫 AddServerSideBlazor之後,註冊服務 範圍

builder.Services.AddServerSideBlazor();

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

在 Blazor Server 應用程式中,使用 AddScoped 呼叫 AddServerSideBlazor之後,註冊服務 範圍

services.AddServerSideBlazor();

services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

CustomAuthStateProvider 服務會在 Program 檔案中註冊: 使用 AddSingleton註冊服務 單一

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

如果不存在,請將 @using 陳述式新增至 _Imports.razor 檔案,讓 Microsoft.AspNetCore.Components.Authorization 命名空間可在元件之間使用:

@using Microsoft.AspNetCore.Components.Authorization;

Router 元件定義中確認或變更路由檢視元件 AuthorizeRouteViewRouter 元件的位置會根據應用程式類型而有所不同。 如果您不知道元件在專案中的位置,請使用搜尋來尋找元件。

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

注意

當您從其中一個已啟用驗證的 Blazor 專案範本建立 Blazor 應用程式時,此應用程式會包含 AuthorizeRouteView 元件。 如需詳細資訊,請參閱 ASP.NET Core Blazor 驗證與授權,以及本文的使用 Router 元件自訂未經授權的內容一節中呈現的其他資訊。

Router 元件所在位置:

Router 元件的位置會根據應用程式類型而有所不同。 如果您不知道元件在專案中的位置,請使用搜尋來尋找元件。

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

注意

當您從其中一個已啟用驗證的 Blazor 專案範本建立 Blazor 應用程式時,此應用程式會包含 AuthorizeRouteViewCascadingAuthenticationState 元件。 如需詳細資訊,請參閱 ASP.NET Core Blazor 驗證與授權,以及本文的使用 Router 元件自訂未經授權的內容一節中呈現的其他資訊。

下列範例 AuthorizeView 元件示範已驗證的使用者名稱:

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

如需使用 AuthorizeView 的指引,請參閱 ASP.NET Core Blazor 驗證和授權

驗證狀態變更通知

自訂 AuthenticationStateProvider 可以在 AuthenticationStateProvider 基底類別上叫用 NotifyAuthenticationStateChanged,以通知取用者要重新轉譯驗證狀態變更。

下列範例是以實作自訂 AuthenticationStateProvider 為基礎,方法是遵循 實作自訂 AuthenticationStateProvider 章節中的指導。 如果您已遵循該章節的指導,下列 CustomAuthStateProvider 將取代章節中所示的內容。

下列 CustomAuthStateProvider 實作會公開自訂方法 AuthenticateUser,以登入使用者並通知取用者驗證狀態變更。

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)));
    }
}

注意

上述建立新 ClaimsIdentity 的程式碼使用 C# 12 (.NET 8) 引進的簡易集合初始化。 如需詳細資訊,請參閱 集合表達 - C# 語言參考

在 元件中:

@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);
    }
}

您可以增強上述方法,透過自訂服務觸發驗證狀態變更的通知。 下列 CustomAuthenticationService 程式碼會在支援欄位 (currentUser) 中使用驗證狀態提供者可以訂閱的事件 (UserChanged),維護目前使用者的宣告主體,此事件會在該處呼叫 NotifyAuthenticationStateChanged。 透過本節稍後的其他設定,CustomAuthenticationService 可以透過將 CurrentUser 設定為觸發 UserChanged 事件的邏輯插入至元件。

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 檔案中,於相依性插入容器中註冊 CustomAuthenticationService

builder.Services.AddScoped<CustomAuthenticationService>();

Startup.csStartup.ConfigureServices 中,於相依性插入容器中註冊 CustomAuthenticationService

services.AddScoped<CustomAuthenticationService>();

Program 檔案中,於相依性插入容器中註冊 CustomAuthenticationService

builder.Services.AddSingleton<CustomAuthenticationService>();

下列 CustomAuthStateProvider 會訂閱 CustomAuthenticationService.UserChanged 事件。 GetAuthenticationStateAsync 方法會傳回使用者的驗證狀態。 一開始,驗證狀態是以 CustomAuthenticationService.CurrentUser 的值為基礎。 當使用者發生變更時,系統會以新的使用者 (new AuthenticationState(newUser)) 建立新的驗證狀態,以呼叫 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);
}

下列元件的 SignIn 方法會為要在 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;
    }
}

注意

上述建立新 ClaimsIdentity 的程式碼使用 C# 12 (.NET 8) 引進的簡易集合初始化。 如需詳細資訊,請參閱 集合表達 - C# 語言參考

其他資源