次の方法で共有


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 の呼び出しで SerializeAllClaimstrue に設定します。

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.csStartup.ConfigureServices に登録されます。

using Microsoft.AspNetCore.Components.Authorization;

...

services.AddServerSideBlazor();

...

services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

AuthorizeRouteViewRouter コンポーネントにあることを確認するか、これを追加します。

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 コンポーネントを使用して承認されていないコンテンツをカスタマイズする」セクションの追加情報をご覧ください。

AuthorizeRouteViewCascadingAuthenticationStateRouter コンポーネントにあることを確認するか、これらを追加します。

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

Note

認証が有効にされた 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 の実装では、ユーザーをサインインさせて、認証状態の変更をコンシューマーに通知するために、カスタム メソッド 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 を挿入する。
  • ユーザーの識別子を保持するフィールドを追加します。
  • ボタンと、AuthenticationStateProviderCustomAuthStateProvider にキャストしてからユーザーの識別子を使って 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.csStartup.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.csStartup.ConfigureServices で:

services.AddScoped<ExampleService>();

次の InjectAuthStateProvider コンポーネントでは、以下のことを行います。

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 コンポーネント内のコンテンツ) が表示されないようにするには、次のいずれかの方法を採用します。

  • プリレンダリングを無効にする: ルート コンポーネントではないアプリのコンポーネント階層の最上位コンポーネントで、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 つの抽象化が関与します。

注意

通常、.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));

その他のリソース