ASP.NET Core Blazor 驗證狀態
注意
這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。
警告
不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。
本文說明如何建立自訂 驗證狀態提供者 ,並在程式碼中接收使用者驗證狀態變更通知。
伺服器端和用戶端 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 類別,透過下列成員提供有關目前使用者驗證狀態的相關資訊:
- GetAuthenticationStateAsync:以非同步方式取得目前使用者的驗證狀態。
- AuthenticationStateChanged:當驗證狀態變更時提供通知的事件。 例如,如果使用者登入或登出應用程式,可能會引發此事件。
- NotifyAuthenticationStateChanged:引發驗證狀態變更事件。
實作自訂 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.cs
的 Startup.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 元件定義中確認或變更路由檢視元件 AuthorizeRouteView 。 Router
元件的位置會根據應用程式類型而有所不同。 如果您不知道元件在專案中的位置,請使用搜尋來尋找元件。
<Router ...>
<Found ...>
<AuthorizeRouteView RouteData="routeData"
DefaultLayout="typeof(Layout.MainLayout)" />
...
</Found>
</Router>
注意
當您從其中一個已啟用驗證的 Blazor 專案範本建立 Blazor 應用程式時,此應用程式會包含 AuthorizeRouteView 元件。 如需詳細資訊,請參閱 ASP.NET Core Blazor 驗證與授權,以及本文的使用 Router
元件自訂未經授權的內容一節中呈現的其他資訊。
Router 元件所在位置:
- 確認或變更路由檢視元件為 AuthorizeRouteView。
- 確認或在 Router 周圍新增 CascadingAuthenticationState 元件。
Router
元件的位置會根據應用程式類型而有所不同。 如果您不知道元件在專案中的位置,請使用搜尋來尋找元件。
<CascadingAuthenticationState>
<Router ...>
<Found ...>
<AuthorizeRouteView RouteData="routeData"
DefaultLayout="typeof(MainLayout)" />
...
</Found>
</Router>
</CascadingAuthenticationState>
注意
當您從其中一個已啟用驗證的 Blazor 專案範本建立 Blazor 應用程式時,此應用程式會包含 AuthorizeRouteView 和 CascadingAuthenticationState 元件。 如需詳細資訊,請參閱 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# 語言參考。
在 元件中:
- 插入 AuthenticationStateProvider。
- 新增欄位來保留使用者的識別碼。
- 新增按鈕和方法,以將 AuthenticationStateProvider 轉換成
CustomAuthStateProvider
,並以使用者的識別碼呼叫AuthenticateUser
。
@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.cs
的 Startup.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# 語言參考。