ASP.NET Core のサーバー側の Blazor アプリを保護する
Note
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、「.NET および .NET Core サポート ポリシー」を参照してください。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
この記事では、サーバー側の Blazor アプリを ASP.NET Core アプリケーションとしてセキュリティで保護する方法について説明します。
サーバー側の Blazor アプリは、セキュリティについて ASP.NET Core アプリと同じ方法で構成されています。 詳細については、「ASP.NET Core Security の概要」を参照してください。
認証コンテキストはアプリの起動時、つまりアプリが WebSocket 最初に接続するときにのみ確立されます。 認証コンテキストは、回線の有効期間を通して維持されます。 アプリは、ユーザーの認証状態を定期的 (現在の既定値は 30 分ごと) に再検証します。
アプリでカスタム サービス用にユーザーをキャプチャしたり、ユーザーに対する更新に対応したりする必要がある場合は、「サーバー側の ASP.NET Core Blazor の追加のセキュリティ シナリオ」をご覧ください。
Blazor は、すべてのページ ナビゲーションで cookie を使って新しい HTTP 要求を行う従来のサーバーでレンダリングされる Web アプリとは異なるものです。 ナビゲーション イベントの間に認証がチェックされます。 ただし、cookie は関係しません。 Cookie は、サーバーに対して HTTP 要求を行うときにのみ送信され、ユーザーが Blazor アプリ内を移動したときには行われません。 ナビゲーションの間に、ユーザーの認証状態が Blazor 回線内でチェックされ、ユーザーは RevalidatingAuthenticationStateProvider
抽象化を使ってサーバー上でいつでもこれを更新できます。
重要
カスタム NavigationManager
を実装してナビゲーションの間に認証の検証を行うことは推奨されません。 ナビゲーションの間にアプリでカスタム認証状態ロジックを実行する必要がある場合は、カスタム AuthenticationStateProvider
を使います。
Note
この記事のコード例では、null 許容参照型 (NRT) と .NET コンパイラの null 状態スタティック分析を採用しています。これは、.NET 6 以降の ASP.NET Core でサポートされています。 ASP.NET Core 5.0 以前をターゲットとする場合は、この記事の例から null 型の指定 (?
) を削除してください。
プロジェクト テンプレート
「ASP.NET Core Blazor 用のツール」のガイダンスに従って、新しいサーバー側の Blazor アプリを作成します。
サーバー側のアプリ テンプレートを選択し、プロジェクトを構成したら、[認証の種類] でアプリの認証を選択します。
- なし (既定値): 認証なし。
- [個別のアカウント]: ユーザー アカウントは、ASP.NET Core Identity を使用してアプリ内に格納されます。
- なし (既定値): 認証なし。
- [個別のアカウント]: ユーザー アカウントは、ASP.NET Core Identity を使用してアプリ内に格納されます。
- [Microsoft ID プラットフォーム]: 詳しくは、ASP.NET Core Blazor の認証と認可に関する記事を参照してください。
- [Windows]: Windows 認証を使用します。
BlazorIdentity UI (個人アカウント)
Blazor では、[個人アカウント] の認証オプションを選んだ場合の、完全な Blazor ベースの Identity UI の生成がサポートされます。
Blazor Web アプリ テンプレートで SQL Server データベースの Identity コードがスキャフォールディングされます。 コマンド ライン バージョンでは、既定で SQLite が使用され、Identity の SQLite データベースが含まれています。
テンプレートでは次の処理が行われます。
- ユーザーのサインインとサインアウトなど、日常的な認証タスクの IdentityRazor コンポーネントと関連ロジックを追加します。
- また、Identity コンポーネントでは、アカウントの確認やパスワードの回復、サード パーティ製アプリを使用した多要素認証などの高度な Identity 機能もサポートされています。
- 対話型サーバー側レンダリング (対話型 SSR) とクライアント側レンダリング (CSR) のシナリオがサポートされています。
- Identity 関連のパッケージと依存関係を追加する。
_Imports.razor
の Identity パッケージを参照する。- カスタム ユーザー Identity クラス (
ApplicationUser
) を作成します。 - EF Core データベース コンテキスト (
ApplicationDbContext
) を作成して登録します。 - 組み込み Identity エンドポイントのルーティングを構成します。
- Identity 検証とビジネス ロジックを含める。
Blazor フレームワークの Identity コンポーネントを調べるには、Blazor Web アプリ プロジェクト テンプレート内の Account
フォルダー (参照ソース) の Pages
および Shared
フォルダー内でそれらにアクセスします。
対話型 WebAssembly または対話型自動レンダリング モードを選択すると、サーバーはすべての認証要求と認可要求を処理し、Identity コンポーネントは Blazor Web アプリのメイン プロジェクト内のサーバー上で静的にレンダリングします。
このフレームワークは、ユーザーの認証状態をブラウザーにフローするためのカスタム AuthenticationStateProvider をサーバー プロジェクトとクライアント (.Client
) プロジェクトの両方で提供します。 サーバー プロジェクトは AddAuthenticationStateSerialization
を呼び出し、クライアント プロジェクトは AddAuthenticationStateDeserialization
を呼び出します。 クライアントではなくサーバーで認証を行うことで、アプリはプリレンダリング中と Blazor WebAssembly ランタイムの初期化前に認証状態にアクセスできます。 カスタムの AuthenticationStateProvider の実装は、Persistent Component State サービス (PersistentComponentState) を使用して認証状態を HTML コメントにシリアル化し、その後に WebAssembly からそれを再度読み取って新しい AuthenticationState インスタンスを作成します。 詳細については、「Blazor Web アプリでの認証状態の管理」セクションを参照してください。
対話型サーバー ソリューションの場合にのみ、IdentityRevalidatingAuthenticationStateProvider
(参照ソース) は、対話型回線が接続されてから 30 分ごとに接続されたユーザーのセキュリティ スタンプを再検証するサーバー側 AuthenticationStateProvider となります。
対話型 WebAssembly または対話型自動レンダリング モードを選択すると、サーバーはすべての認証要求と認可要求を処理し、Identity コンポーネントは Blazor Web アプリのメイン プロジェクト内のサーバー上で静的にレンダリングします。 プロジェクト テンプレートには、.Client
プロジェクトに PersistentAuthenticationStateProvider
クラス (参照ソース) が含まれており、サーバーとブラウザーの間でユーザーの認証状態を同期します。 このクラスは、AuthenticationStateProvider のカスタム実装です。 このプロバイダーは、Persistent Component State サービス (PersistentComponentState) を使用して認証状態をプリレンダリングし、それをページに保持します。
Blazor Web アプリのメイン プロジェクトでは、認証状態プロバイダーの名前は IdentityRevalidatingAuthenticationStateProvider
(参照ソース) (サーバーのインタラクティビティ ソリューションのみ) または PersistingRevalidatingAuthenticationStateProvider
(参照ソース) (WebAssembly または自動インタラクティビティ ソリューション) です。
BlazorIdentity は、ファクトリで作成されていない DbContext インスタンスに依存します。これは、プロジェクト テンプレートの Identity コンポーネントが対話機能をサポートせずに静的にレンダリングするには DbContext で十分であるため、意図的なものです。
Identity コンポーネントに対して同時に静的 SSR を適用しているときに、グローバル インタラクティブレンダリング モードがどのように非 Identity コンポーネントに適用されるかについては、「ASP.NET Core の Blazor レンダリング モード」を参照してください。
プリレンダリングされた状態の永続化の詳細については、「ASP.NET Core Razor コンポーネントのプリレンダリング」を参照してください。
BlazorIdentity UI の詳細と、ソーシャル Web サイトを介した外部ログインの統合に関するガイダンスについては、「.NET 8 の ID の新機能」を参照してください。
Note
通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。
Blazor Web アプリで認証状態を管理する
このセクションは、以下を採用する Blazor Web アプリに適用されます。
- 個人アカウント
- クライアント側レンダリング (CSR、WebAssembly ベースの対話性)。
クライアント側認証状態プロバイダーは、Blazor でのみ使用され、ASP.NET Core 認証システムと統合されません。 プリレンダリング中、Blazor によりページで定義されたメタデータが考慮され、ASP.NET Core 認証システムを使用して、ユーザーが認証されているかどうかが判断されます。 ユーザーが 1 つのページから別のページに移動すると、クライアント側の認証プロバイダーが使用されます。 ユーザーがページを更新すると (ページ全体の再読み込み)、クライアント側の認証状態プロバイダーはサーバーでの認証の決定に関与しません。 ユーザーの状態はサーバーによって保持されないため、クライアント側で維持されていた認証状態は失われます。
これに対処するには、ASP.NET Core 認証システム内で認証を実行するのが最適な方法です。 クライアント側の認証状態プロバイダーでは、ユーザーの認証状態の反映のみが処理されます。 認証状態プロバイダーでこれを実現する方法の例は、Blazor Web アプリ プロジェクト テンプレートによって以下に示されています。
以下のように、サーバー プロジェクトの Program
ファイル内で AddAuthenticationStateSerialization
を呼び出します。これによって Persistent Component State サービス (PersistentComponentState) を使用してサーバー側 AuthenticationStateProvider によって返された AuthenticationState がシリアル化されます。
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization();
既定では、この API がシリアル化するのは、ブラウザーでアクセスするためのサーバー側の名前とロールの要求だけです。 すべての要求を含めるには、以下のように、サーバー側の AddAuthenticationStateSerialization
の呼び出しで SerializeAllClaims
を true
に設定します。
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization(
options => options.SerializeAllClaims = true);
クライアント (.Client
) プロジェクトの Program
ファイル内で、AddAuthenticationStateDeserialization
を呼び出します。これによって AuthenticationStateData
および Persistent Component State サービス (PersistentComponentState) を使用してサーバーから逆シリアル化された AuthenticationState の状態で AuthenticationStateProvider が追加されます。 サーバー プロジェクトには、対応する AddAuthenticationStateSerialization
の呼び出しが必要です。
builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthenticationStateDeserialization();
PersistingRevalidatingAuthenticationStateProvider
(参照ソース): 対話型サーバー側レンダリング (対話型 SSR) とクライアント側レンダリング (CSR) を採用する Blazor Web Apps の場合。 これは、対話型回線が接続されているときに 30 分ごとに、接続されたユーザーのセキュリティ スタンプを再検証するサーバー側 AuthenticationStateProvider です。 また、永続的コンポーネント状態サービスを使用して認証状態をクライアントにフローし、CSR の有効期間中は固定します。PersistingServerAuthenticationStateProvider
(参照ソース): CSR のみを採用する Blazor Web Apps の場合。 これは、永続的コンポーネント状態サービスを使用してクライアントに認証状態をフローするサーバー側の AuthenticationStateProvider であり、CSR の有効期間中は固定されます。PersistentAuthenticationStateProvider
(参照ソース): CSR を採用する Blazor Web Apps の場合。 これは、サーバーにレンダリングされたときにページに保持されるデータを探して、ユーザーの認証状態を決定するクライアント側 AuthenticationStateProvider です。 この認証状態は、CSR の有効期間中は固定されます。 ユーザーがログインまたはログアウトする必要がある場合は、ページ全体の再読み込みが必要です。 これにより提供されるのは、表示目的のユーザー名とメールのみです。 以降の要求を行うときにサーバーに対して認証するトークンは含まれません。これは、サーバーへのHttpClient
要求に含まれる cookie を使用して個別に処理されます。
Note
通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。
スキャフォールディング Identity
サーバー側の Blazor アプリへの Identity のスキャフォールディングについて詳しくは、「ASP.NET Core プロジェクトでの Identity のスキャフォールディング」をご覧ください。
サーバー側の Blazor アプリに Identity をスキャフォールディングします。
外部プロバイダーからの追加のクレームとトークン
外部プロバイダーからの追加の要求を格納するには、「ASP.NET Core で外部プロバイダーからの追加の要求とトークンを保持する」を参照してください。
Identity Server を使用した Azure App Service on Linux
Identity Server を使用して Azure App Service on Linux にデプロイするときに、発行者を明示的に指定します。 詳しくは、「Identity を使用して SPA の Web API バックエンドをセキュリティで保護する方法」を参照してください。
カスタムの AuthenticationStateProvider
を実装する
アプリでカスタム プロバイダーが必要な場合は、AuthenticationStateProvider を実装して、GetAuthenticationStateAsync をオーバーライドします。
前の例では、すべてのユーザーがユーザー名 mrfibuli
で認証されます。
CustomAuthStateProvider.cs
:
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;
public class CustomAuthStateProvider : AuthenticationStateProvider
{
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, "mrfibuli"),
}, "Custom Authentication");
var user = new ClaimsPrincipal(identity);
return Task.FromResult(new AuthenticationState(user));
}
}
CustomAuthStateProvider
サービスは Program
ファイルに登録されます。
using Microsoft.AspNetCore.Components.Authorization;
...
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();
CustomAuthStateProvider
サービスは、AddServerSideBlazor の呼び出し "後" に、Program
ファイルに登録されます。
using Microsoft.AspNetCore.Components.Authorization;
...
builder.Services.AddServerSideBlazor();
...
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();
CustomAuthStateProvider
サービスは、AddServerSideBlazor の呼び出しの "後" で、Startup.cs
の Startup.ConfigureServices
に登録されます。
using Microsoft.AspNetCore.Components.Authorization;
...
services.AddServerSideBlazor();
...
services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();
AuthorizeRouteView が Router コンポーネントにあることを確認するか、これを追加します。
Routes
コンポーネント (Components/Routes.razor
) 内は、次のようになっています。
<Router ...>
<Found ...>
<AuthorizeRouteView RouteData="routeData"
DefaultLayout="typeof(Layout.MainLayout)" />
...
</Found>
</Router>
カスケード認証状態サービスを Program
ファイル内のサービス コレクションに追加します。
builder.Services.AddCascadingAuthenticationState();
Note
認証が有効にされた Blazor プロジェクト テンプレートのいずれかから Blazor アプリを作成すると、アプリには AuthorizeRouteView と、AddCascadingAuthenticationState への呼び出しが組み込まれます。 詳しくは、「ASP.NET Core Blazor の認証と承認」と、その記事の「Router コンポーネントを使用して承認されていないコンテンツをカスタマイズする」セクションの追加情報をご覧ください。
AuthorizeRouteView と CascadingAuthenticationState が Router コンポーネントにあることを確認するか、これらを追加します。
<CascadingAuthenticationState>
<Router ...>
<Found ...>
<AuthorizeRouteView RouteData="routeData"
DefaultLayout="typeof(MainLayout)" />
...
</Found>
</Router>
</CascadingAuthenticationState>
Note
認証が有効にされた 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
の実装では、ユーザーをサインインさせて、認証状態の変更をコンシューマーに通知するために、カスタム メソッド AuthenticateUser
を公開してします。
CustomAuthStateProvider.cs
:
using System.Security.Claims;
using System.Threading.Tasks;
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[]
{
new Claim(ClaimTypes.Name, userIdentifier),
}, "Custom Authentication");
var user = new ClaimsPrincipal(identity);
NotifyAuthenticationStateChanged(
Task.FromResult(new AuthenticationState(user)));
}
}
コンポーネントでは:
- 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);
}
}
@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);
}
}
上記のアプローチを拡張し、カスタム サービスを使って認証状態の変更の通知をトリガーできます。 次の AuthenticationService
は、AuthenticationStateProvider がサブスクライブできるイベント (UserChanged
) で、ユーザーの要求プリンシパルをバッキング フィールド (currentUser
) に保持します。イベントは NotifyAuthenticationStateChanged を呼び出します。 このセクションで後ほど示す追加の構成では、CurrentUser
を設定して UserChanged
イベントをトリガーするロジックと共に、AuthenticationService
をコンポーネントに挿入できます。
using System.Security.Claims;
public class AuthenticationService
{
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
ファイルで、AuthenticationService
を依存関係挿入コンテナーに登録します。
builder.Services.AddScoped<AuthenticationService>();
Startup.cs
の Startup.ConfigureServices
で、AuthenticationService
を依存関係挿入コンテナーに登録します。
services.AddScoped<AuthenticationService>();
次の CustomAuthStateProvider
は、AuthenticationService.UserChanged
イベントをサブスクライブします。 GetAuthenticationStateAsync
はユーザーの認証状態を返します。 初期状態で認証状態は AuthenticationService.CurrentUser
の値に基づいています。 ユーザーに変更があると、GetAuthenticationStateAsync
への呼び出しに対して、新しいユーザー (new AuthenticationState(newUser)
) を使って新しい認証状態が作成されます。
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;
public class CustomAuthStateProvider : AuthenticationStateProvider
{
private AuthenticationState authenticationState;
public CustomAuthStateProvider(AuthenticationService service)
{
authenticationState = new AuthenticationState(service.CurrentUser);
service.UserChanged += (newUser) =>
{
authenticationState = new AuthenticationState(newUser);
NotifyAuthenticationStateChanged(
Task.FromResult(new AuthenticationState(newUser)));
};
}
public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
Task.FromResult(authenticationState);
}
次のコンポーネントの SignIn
メソッドでは、AuthenticationService.CurrentUser
に設定するために、ユーザーの識別子の要求プリンシパルが作成されます。
@inject AuthenticationService AuthenticationService
<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 = AuthenticationService.CurrentUser;
var identity = new ClaimsIdentity(
new[]
{
new Claim(ClaimTypes.Name, userIdentifier),
},
"Custom Authentication");
var newUser = new ClaimsPrincipal(identity);
AuthenticationService.CurrentUser = newUser;
}
}
@inject AuthenticationService AuthenticationService
<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 = AuthenticationService.CurrentUser;
var identity = new ClaimsIdentity(
new[]
{
new Claim(ClaimTypes.Name, userIdentifier),
},
"Custom Authentication");
var newUser = new ClaimsPrincipal(identity);
AuthenticationService.CurrentUser = newUser;
}
}
コンポーネントにスコープ設定されたサービス用の AuthenticationStateProvider
を挿入する
正しく初期化されていない AuthenticationStateProvider の新しいインスタンスが作成されるため、カスタム スコープ内で AuthenticationStateProvider の解決を試みないでください。
コンポーネントにスコープ設定されたサービス内の AuthenticationStateProvider にアクセスするには、@inject
ディレクティブまたは [Inject]
属性を使用して AuthenticationStateProvider を挿入し、それをパラメーターとしてサービスに渡します。 この方法により、AuthenticationStateProvider の正しい初期化されたインスタンスが各ユーザー アプリ インスタンスに確実に使われます。
ExampleService.cs
:
public class ExampleService
{
public async Task<string> ExampleMethod(AuthenticationStateProvider authStateProvider)
{
var authState = await authStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity is not null && user.Identity.IsAuthenticated)
{
return $"{user.Identity.Name} is authenticated.";
}
else
{
return "The user is NOT authenticated.";
}
}
}
サービスをスコープとして登録します。 サーバー側の Blazor アプリでは、スコープが設定されたサービスの有効期間は、クライアント接続回線の期間と同じです。
Program
ファイル:
builder.Services.AddScoped<ExampleService>();
Startup.cs
の Startup.ConfigureServices
で:
services.AddScoped<ExampleService>();
次の InjectAuthStateProvider
コンポーネントでは、以下のことを行います。
- コンポーネントは OwningComponentBase を継承します。
- AuthenticationStateProvider が挿入されて、
ExampleService.ExampleMethod
に渡されます。 ExampleService
は、OwningComponentBase.ScopedServices と GetRequiredService を使って解決されます。これは、ユーザーの回線の有効期間を通して存在するExampleService
の正しい初期化されたインスタンスを返します。
InjectAuthStateProvider.razor
:
@page "/inject-auth-state-provider"
@inherits OwningComponentBase
@inject AuthenticationStateProvider AuthenticationStateProvider
<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>
<p>@message</p>
@code {
private string? message;
private ExampleService? ExampleService { get; set; }
protected override async Task OnInitializedAsync()
{
ExampleService = ScopedServices.GetRequiredService<ExampleService>();
message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
}
}
@page "/inject-auth-state-provider"
@inject AuthenticationStateProvider AuthenticationStateProvider
@inherits OwningComponentBase
<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>
<p>@message</p>
@code {
private string? message;
private ExampleService? ExampleService { get; set; }
protected override async Task OnInitializedAsync()
{
ExampleService = ScopedServices.GetRequiredService<ExampleService>();
message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
}
}
詳しくは、「ASP.NET Core Blazor 依存関係の挿入」で OwningComponentBase についてのガイダンスをご覧ください。
カスタム AuthenticationStateProvider
を使用したプリレンダリング中に未承認のコンテンツが表示される
カスタムの AuthenticationStateProvider
を使ってプリレンダリング中に、認可されていないコンテンツ (たとえば、AuthorizeView
コンポーネント内のコンテンツ) が表示されないようにするには、次のいずれかの方法を採用します。
プリレンダリングをサポートするカスタム AuthenticationStateProvider に対して IHostEnvironmentAuthenticationStateProvider を実装する。IHostEnvironmentAuthenticationStateProvider の実装例については、
ServerAuthenticationStateProvider.cs
(参照ソース) で Blazor フレームワークの ServerAuthenticationStateProvider の実装を参照してください。Note
通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。
プリレンダリングを無効にする: ルート コンポーネントではないアプリのコンポーネント階層の最上位コンポーネントで、
prerender
パラメーターをfalse
に設定してレンダリング モードを指定します。Note
ルート コンポーネントを対話型にすること (
App
コンポーネントなど) はサポートされていません。 そのため、プリレンダリングをApp
コンポーネントで直接無効にすることはできません。Blazor Web アプリ プロジェクト テンプレートに基づくアプリの場合、プリレンダリングの無効化は通常、
App
コンポーネント内でRoutes
コンポーネントが使用されている場所 (Components/App.razor
) で行います。<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
また、
HeadOutlet
コンポーネントのプリレンダリングを無効にします。<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Routes
コンポーネント インスタンスに適用されるレンダリング モードを選択的に制御することもできます。 たとえば、「ASP.NET Core Blazor レンダリング モード」を参照してください。
プリレンダリングを無効にする。
_Host.cshtml
ファイルを開き、コンポーネント タグ ヘルパーのrender-mode
属性を、Server に変更します。<component type="typeof(App)" render-mode="Server" />
- アプリが起動する前にサーバーでユーザーを認証する。このアプローチを採用するには、アプリが Identity ベースのサインイン ページを使用してユーザーの初期要求に応答するか、Blazor エンドポイントへの要求を監視して、認証されるまで防ぐ必要があります。 詳細については、「認可によって保護されたユーザー データを使って ASP.NET Core アプリを作成する」を参照してください。 認証後は、プリレンダリングされた Razor コンポーネント内の未承認のコンテンツは、ユーザーがコンテンツを表示することが本当に承認されたときにのみ表示されます。
ユーザー状態の管理
名前には "state" という単語が含まれますが、AuthenticationStateProvider は "一般的なユーザーの状態" を格納するためのものではありません。 AuthenticationStateProvider は、ユーザーの認証状態 (アプリにサインインしているかどうか、サインインに使われているユーザー) をアプリに示すだけです。
認証は、Razor Pages および MVC アプリと同じ ASP.NET Core Identity 認証を使用します。 ASP.NET Core Identity に格納されたユーザー状態は、アプリにコードを追加しなくても Blazor に流れます。 アプリの Blazor 部分で Identity の機能を有効にするには、ASP.NET Core Identity の記事とチュートリアルのガイダンスに従ってください。
ASP.NET Core Identity の外部での一般的な状態管理のガイダンスについては、「ASP.NET Core Blazor 状態管理」をご覧ください。
追加のセキュリティ抽象化
認証状態の管理には、さらに 2 つの抽象化が関与します。
ServerAuthenticationStateProvider (参照リソース): サーバーから認証状態を取得するために Blazor フレームワークが使う AuthenticationStateProvider。
RevalidatingServerAuthenticationStateProvider (参照リソース): Blazor フレームワークがホスト環境から認証状態を受け取り、定期的に再検証するために使う AuthenticationStateProvider サービスの基底クラス。
既定の 30 分間の再検証間隔は、
RevalidatingIdentityAuthenticationStateProvider
(Areas/Identity/RevalidatingIdentityAuthenticationStateProvider.cs
) で調整できます。 次の例では、間隔を 20 分に短縮しています。protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(20);
注意
通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。
一時的なリダイレクト URL の有効期間
"このセクションは Blazor WebAssembly に適用されます。"
Blazor サーバー側レンダリングによって出力される一時的なリダイレクト URL のデータ保護有効期間を、RazorComponentsServiceOptions.TemporaryRedirectionUrlValidityDuration オプションを使用して取得するか、設定します。 これらは一時的にしか使用されないため、その有効期間は、クライアントで URL を受信し、ナビゲーションを開始するために必要な長さであれば十分です。 ただし、サーバー間のクロック スキューを許可するために十分な長さも必要です。 既定値は 5 分です。
次の例では、値は 7 分に延長されています。
builder.Services.AddRazorComponents(options =>
options.TemporaryRedirectionUrlValidityDuration =
TimeSpan.FromMinutes(7));
その他のリソース
- クイック スタート:Microsoft でのサインインを ASP.NET Core Web アプリに追加する
- クイック スタート:Microsoft ID プラットフォームを使用して ASP.NET Core Web API を保護する
- プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する: 次のガイダンスが含まれます。
- 転送されたヘッダー ミドルウェアを使用した、プロキシ サーバーと内部ネットワークの間での HTTPS スキーム情報の保持。
- 追加のシナリオとユース ケース (手動スキーム構成を含む)、正しい要求ルーティングのための要求パスの変更、Linux および IIS 以外のリバース プロキシのための要求スキームの転送。
ASP.NET Core