ASP.NET Core Blazor WebAssembly をセキュリティで保護する
注意
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
Blazor WebAssembly アプリは、シングル ページ アプリケーション (SPA) と同じ方法でセキュリティ保護します。 ユーザーを SPA で認証する方法はいくつかありますが、最も一般的で包括的な方法は、OpenID Connect (OIDC) などの OAuth 2.0 プロトコルに基づく実装を使用することです。
Blazor WebAssembly のセキュリティ ドキュメントでは、主にユーザー認証と承認のタスクを実行する方法に焦点を当てています。 OAuth 2.0/OIDC の一般的な概念の対象範囲については、主要な概要に関する記事の「その他のリソース」セクションのリソースを参照してください。
機密データと資格情報のクライアント側/SPA セキュリティ
Blazor WebAssembly アプリの .NET/C# コードベースはクライアントに提供されるので、アプリのコードをユーザーによる検査や改ざんから保護することはできません。 アプリ シークレット、接続文字列、パスワード、プライベート .NET/C# コード、その他の機密データなど、資格情報やシークレットをBlazor WebAssembly アプリに配置しないでください。
.NET/C# コードを保護し、ASP.NET Core データ保護機能を使用してデータをセキュリティで保護するには、サーバー側 ASP.NET Core Web API を使用します。 セキュリティで保護されたアプリ機能とデータ処理のためには、クライアント側 Blazor WebAssembly アプリがサーバー側 Web API を呼び出すようにします。 詳細については、「ASP.NET Core Blazor アプリからの Web API の呼び出し」とこのノード内の記事を参照してください。
ローカル開発テストでは、機密データをセキュリティで保護するために、 Secret Manager ツール をお勧めします。
認証ライブラリ
Blazor WebAssemblyでは、Microsoft identity プラットフォームを使用したMicrosoft.AspNetCore.Components.WebAssembly.Authentication
ライブラリ経由で OIDC を使用したアプリの認証と承認をサポートしています ライブラリには、ASP.NET Core バックエンドに対してシームレスに認証を行うための一連のプリミティブが用意されています。 このライブラリは、OpenID Provider (OP) と呼ばれる OIDC をサポートするすべてのサードパーティ Identity プロバイダー (IP) に対して認証できます。
Blazor WebAssembly ライブラリ (Authentication.js
) の認証のサポートは、基になる認証プロトコルの詳細を処理するために使用される、Microsoft Authentication Library (MSAL、msal.js
) に基づいて構築されています。 Blazor WebAssembly ライブラリでは、Proof Key for Code Exchange (PKCE) 認可コード フローのみがサポートされます。 暗黙的な許可はサポートされていません。
SameSite Cookie の使用など、SPA を認証するためのその他のオプションも存在します。 ただし、Blazor WebAssembly のエンジニアリング設計では、Blazor WebAssembly アプリでの認証に最適なオプションとして OAuth および OIDC が使用されます。 JSON Web トークン (JWT) に基づくトークンベースの認証は、機能とセキュリティ上の理由により、cookie ベースの認証に基づいて選択されています。
- トークンベースのプロトコルを使用すると、トークンがすべての要求で送信されないため、脆弱性が低減されます。
- トークンはサーバーに明示的に送信されるため、サーバー エンドポイントでは、クロスサイト リクエスト フォージェリ (CSRF) に対する保護が必要ありません。 これにより、MVC または Razor ページ アプリと共に、Blazor WebAssembly アプリをホストすることができます。
- トークンの権限は Cookie よりも狭くなります。 たとえば、該当する機能が明示的に実装されていない限り、トークンを使用してユーザー アカウントを管理したり、ユーザーのパスワードを変更したりできません。
- トークンの有効期間は短く、1 時間です。これにより、攻撃領域が制限されます。 トークンは、いつでも取り消すことができます。
- 自己完結型の JWT は、クライアントとサーバーの認証プロセスを保証します。 たとえば、クライアントには、受信したトークンが正当であり、指定した認証プロセスの一環として出力されたことを検出して検証する手段があります。 サード パーティが認証プロセスの途中でトークンを切り替えようとすると、クライアントは切り替えられたトークンを検出して使用しないようにすることができます。
- OAuth および OIDC を使用したトークンは、アプリが安全であることを確認するために、正しく動作しているユーザー エージェントに依存しません。
- OAuth や OIDC などのトークンベースのプロトコルでは、同じセキュリティ特性のセットを使用して、スタンドアロンの Blazor Webassembly アプリのユーザーの認証と認可を行うことができます。
- トークンベースのプロトコルを使用すると、トークンがすべての要求で送信されないため、脆弱性が低減されます。
- トークンはサーバーに明示的に送信されるため、サーバー エンドポイントでは、クロスサイト リクエスト フォージェリ (CSRF) に対する保護が必要ありません。 これにより、MVC または Razor ページ アプリと共に、Blazor WebAssembly アプリをホストすることができます。
- トークンの権限は Cookie よりも狭くなります。 たとえば、該当する機能が明示的に実装されていない限り、トークンを使用してユーザー アカウントを管理したり、ユーザーのパスワードを変更したりできません。
- トークンの有効期間は短く、1 時間です。これにより、攻撃領域が制限されます。 トークンは、いつでも取り消すことができます。
- 自己完結型の JWT は、クライアントとサーバーの認証プロセスを保証します。 たとえば、クライアントには、受信したトークンが正当であり、指定した認証プロセスの一環として出力されたことを検出して検証する手段があります。 サード パーティが認証プロセスの途中でトークンを切り替えようとすると、クライアントは切り替えられたトークンを検出して使用しないようにすることができます。
- OAuth および OIDC を使用したトークンは、アプリが安全であることを確認するために、正しく動作しているユーザー エージェントに依存しません。
- OAuth や OIDC などのトークンベースのプロトコルを使うと、ホストされた Blazor WebAssembly ソリューションのクライアントとスタンドアロン Blazor Webassembly アプリのユーザーを、同じセキュリティ特性のセットを使用して認証および認可できます。
重要
Blazor プロジェクト テンプレートで Duende Identity Server を採用する ASP.NET Core のバージョンの場合、Duende Software から Duende Identity Server の運用環境での使用に対してライセンス料金の支払いを要求されることがあります。 詳細については、「ASP.NET Core 5.0 から 6.0 への移行」を参照してください。
OIDC を使用した認証プロセス
Microsoft.AspNetCore.Components.WebAssembly.Authentication
ライブラリには、OIDC を使用した認証と認可を実装するためのいくつかのプリミティブが用意されています。 大まかにいうと、認証は次のようにして行われます。
- 匿名ユーザーがログイン ボタンを選択するか、
[Authorize]
属性が適用された Razor コンポーネントまたはページを要求すると、そのユーザーはアプリのログイン ページ (/authentication/login
) にリダイレクトされます。 - ログイン ページで、認証ライブラリが承認エンドポイントへのリダイレクトを準備します。 承認エンドポイントは、Blazor WebAssembly アプリの外部にあり、別のオリジンでホストすることができます。 エンドポイントは、ユーザーが認証されているかどうかを判断し、応答として 1 つ以上のトークンを発行する役割を担います。 認証ライブラリは、認証応答を受信するためのログイン コールバックを提供します。
- ユーザーが認証されていない場合、そのユーザーは基になる認証システム (通常は ASP.NET Core の Identity) にリダイレクトされます。
- ユーザーが既に認証されている場合、承認エンドポイントは適切なトークンを生成し、ブラウザーをログイン コールバック エンドポイント (
/authentication/login-callback
) にリダイレクトします。
- Blazor WebAssembly アプリでログイン コールバック エンドポイント (
/authentication/login-callback
) が読み込まれると、認証応答が処理されます。- 認証プロセスが正常に完了した場合、ユーザーは認証され、必要に応じてユーザーが要求した元の保護された URL に戻されます。
- 何らかの理由で認証プロセスが失敗した場合、ユーザーはエラーが表示されたログイン失敗ページ (
/authentication/login-failed
) に送られます。
Authentication
コンポーネント
Authentication
コンポーネント (Authentication.razor
) はリモート認証操作を処理し、次のことをアプリに許可します。
- 認証状態のアプリのルートを構成する。
- 認証状態の UI コンテンツを設定する。
- 認証状態を管理する。
ユーザーの登録やサインインなどの認証アクションは、Blazor フレームワークの RemoteAuthenticatorViewCore<TAuthenticationState> コンポーネントに渡されます。ここでは認証操作全体で状態が保持され、制御されます。
詳細と例については、「ASP.NET Core Blazor WebAssembly のその他のセキュリティ シナリオ」をご覧ください。
承認
Blazor WebAssembly アプリでは、すべてのクライアント側コードがユーザーによって変更される可能性があるため、承認チェックがバイパスされる可能性があります。 JavaScript SPA フレームワークや任意のオペレーティング システム用のネイティブ アプリを含め、すべてのクライアント側アプリのテクノロジにも同じことが当てはまります。
常に、クライアント側アプリからアクセスされるすべての API エンドポイント内のサーバー上で承認チェックを実行します。
認証をカスタマイズする
Blazor WebAssembly には、基になる認証ライブラリのその他のパラメーターを追加および取得して、外部 identity プロバイダーを使ってリモート認証操作を行う方法が備わっています。
追加のパラメーターを渡すために、NavigationManager では、外部の場所を変更する際の履歴エントリ状態の受け渡しと取得がサポートされます。 詳細については、次のリソースを参照してください。
- Blazor の "基礎" > "ルーティングとナビゲーション" に関する記事
- MDN ドキュメント: 履歴 API
履歴 API によって保存される状態には、リモート認証において次の利点があります。
- セキュリティで保護されたアプリ エンドポイントに渡される状態は、
authentication/login
エンドポイントでユーザーを認証するために実行されるナビゲーションに関連付けられます。 - データをエンコードおよびデコードする余分な作業を避けられます。
- 脆弱性が低減されます。 クエリ文字列を使用してナビゲーション状態を保存するのとは異なり、最上位レベルのナビゲーションまたは別の配信元からの影響によって、履歴 API によって保存される状態を設定することはできません。
- 履歴エントリは認証に成功すると置き換えられるため、履歴エントリにアタッチされている状態は削除され、クリーンアップの必要はありません。
InteractiveRequestOptions は、アクセス トークンにログインまたはプロビジョニングするための identity プロバイダーへの要求を表します。
NavigationManagerExtensions は、ログイン操作の NavigateToLogin メソッドとログアウト操作の NavigateToLogout を提供します。 メソッドは NavigationManager.NavigateTo を呼び出し、次のために渡された InteractiveRequestOptions またはメソッドによって作成された新しい InteractiveRequestOptions インスタンスを使用して、履歴エントリの状態を設定します。
- 戻り先 URL の現在の URI を使用したユーザーのサインイン (InteractionType.SignIn)。
- 戻り先 URL を使用したユーザーのサインアウト (InteractionType.SignOut)。
次の認証シナリオについては、「ASP.NET Core Blazor WebAssembly のセキュリティに関するその他のシナリオ」の記事で説明します。
- ログイン プロセスをカスタマイズする
- カスタムの戻り先 URL を使用してログアウトする
- トークンを対話的に取得する前にオプションをカスタマイズする
- IAccessTokenProvider を使用する場合のオプションをカスタマイズする
- 認証オプションからログイン パスを取得する
アプリ全体での承認を要求する
次の "いずれか" の方法を使用して、[Authorize]
属性 (API ドキュメント) をアプリの各 Razor コンポーネントに適用します。
アプリのインポート ファイルで、Microsoft.AspNetCore.Authorization 名前空間の
@using
ディレクティブと、 属性の[Authorize]
@attribute
ディレクティブを追加します。_Imports.razor
:@using Microsoft.AspNetCore.Authorization @attribute [Authorize]
Authentication
コンポーネントへの匿名アクセスを許可して、identity プロバイダーへのリダイレクトを許可します。 次の Razor コードを、@page
ディレクティブの下のAuthentication
コンポーネントに追加します。Authentication.razor
:@using Microsoft.AspNetCore.Components.WebAssembly.Authentication @attribute [AllowAnonymous]
@page
ディレクティブの各 Razor コンポーネントに属性を追加します。@using Microsoft.AspNetCore.Authorization @attribute [Authorize]
Note
RequireAuthenticatedUser を持つポリシーに AuthorizationOptions.FallbackPolicy を設定することはサポートされていません。
アプリごとに 1 つの identity プロバイダー アプリ登録を使用する
この概要の下にある記事の一部は、2 つ以上のアプリが関わる Blazor ホスティング シナリオに関連しています。 スタンドアロン Blazor WebAssembly アプリは、認証されたユーザーと共に Web API を使用してサーバー アプリによって提供されるサーバーのリソースとデータにアクセスします。
これらのシナリオがドキュメントの例で実装されている場合、2 つの identity プロバイダー登録が使用されます。1 つはクライアント アプリ用で、もう 1 つはサーバー アプリ用です。 個別の登録を使用すること (たとえば Microsoft Entra ID で) は、厳密には必要ありません。 ただし、2 つの登録を使用することは、登録がアプリ別に分離されるため、セキュリティ上のベスト プラクティスです。 個別の登録を使用すると、クライアントとサーバーの登録を個別に構成することも可能になります。
この "概要" の下にある記事の一部は、2 つ以上のアプリを使用する次の Blazor ホスティング シナリオのいずれかに関連しています。
- 2 つのアプリで構成された、ホストされている Blazor WebAssembly ソリューション: クライアント側 Blazor WebAssembly アプリとサーバー側 ASP.NET Core ホスト アプリ。 クライアント アプリに対して認証されたユーザーは、サーバー アプリによって提供されるサーバーのリソースとデータにアクセスします。
- 認証されたユーザーと共に Web API を使用してサーバー アプリによって提供されるサーバーのリソースとデータにアクセスする、スタンドアロン Blazor WebAssembly アプリ。 このシナリオはホストされている Blazor WebAssembly ソリューションの使用に似ていますが、このケースでは、クライアント アプリはサーバー アプリによってホストされません。
これらのシナリオがドキュメントの例で実装されている場合、2 つの identity プロバイダー登録が使用されます。1 つはクライアント アプリ用で、もう 1 つはサーバー アプリ用です。 個別の登録を使用すること (たとえば Microsoft Entra ID で) は、厳密には必要ありません。 ただし、2 つの登録を使用することは、登録がアプリ別に分離されるため、セキュリティ上のベスト プラクティスです。 個別の登録を使用すると、クライアントとサーバーの登録を個別に構成することも可能になります。
更新トークン
更新トークンは Blazor WebAssembly アプリではセキュリティで保護できませんが、適切なセキュリティ戦略と共に実装すれば使用できます。
.NET 6 以降の ASP.NET Core のスタンドアロン Blazor WebAssembly アプリの場合は、次を使用することをおすすめします。
- Proof Key for Code Exchange (PKCE) を使用した OAuth 2.0 認可コード フロー (コード)。
- 有効期限が短い更新トークン。
- ローテーションされた更新トークン。
- 有効期限があり、有効期限が切れた後はユーザーの資格情報を更新するために新しい対話型認可フローが要求される更新トークン。
ホストされている Blazor WebAssembly ソリューションの場合、更新トークンはサーバー側アプリで、サードパーティの API にアクセスするために保持および使用することができます。 詳細については、「ASP.NET Core Blazor WebAssembly のその他のセキュリティ シナリオ」を参照してください。
詳細については、次のリソースを参照してください。
ユーザーに対するクレームを確立する
アプリでは、サーバーへの Web API 呼び出しに基づくユーザーへのクレームが必要になることがよくあります。 たとえば、クレームは、アプリで承認を確立するためによく使用されます。 このようなシナリオにおいて、アプリでは、サービスにアクセスするためのアクセス トークンを要求し、そのトークンを使用してクレームを作成するためのユーザー データを取得します。
例については、次のリソースを参照してください。
プリレンダリングのサポート
プリレンダリングは認証エンドポイントではサポートされていません (/authentication/
パス セグメント)。
プリレンダリングは認証エンドポイントではサポートされていません (/authentication/
パス セグメント)。
詳細については、「ASP.NET Core Blazor WebAssembly のその他のセキュリティ シナリオ」を参照してください。
Identity Server を使用した Azure App Service on Linux
Identity Server を使用して Azure App Service on Linux にデプロイするときに、発行者を明示的に指定します。
詳しくは、Identity を使用して SPA の Web API バックエンドをセキュリティで保護する方法に関する記事を参照してください。
Windows 認証
Blazor WebAssembly またはその他の SPA フレームワークでは、Windows 認証を使用しないことをお勧めします。 Windows 認証の代わりにトークンベースのプロトコルを使用することをお勧めします (Active Directory フェデレーション サービス (AD FS) を使用する OIDC など)。
Windows 認証が Blazor WebAssembly またはその他の SPA フレームワークで使用されている場合、クロスサイト リクエスト フォージェリ (CSRF) トークンからアプリを保護するために追加の手段が必要になります。 Cookie に当てはまるのと同じ問題が Windows 認証にも当てはまります。これに加えて、Windows 認証では、オリジン間での認証コンテキストの共有を防ぐメカニズムは提供されません。 CSRF からの追加の保護なしで Windows 認証を使用するアプリは、少なくとも組織のイントラネットに限定する必要があり、オープンなインターネットでは使用すべきではありません。
詳細については、「ASP.NET Core でのクロスサイト リクエスト フォージェリ (XSRF/CSRF) 攻撃の防止」を参照してください。
SignalR ハブをセキュリティで保護する
サーバー API プロジェクトで SignalR ハブをセキュリティで保護するには、[Authorize]
属性をハブ クラスまたはハブ クラスのメソッドに適用します。
ホストされた Blazor WebAssembly (.NET 7 かそれ以前の ASP.NET Core) または Blazor Web App (.NET 8 かそれ以降の ASP.NET Core) など、プリレンダリングを使用するクライアント プロジェクトでは、「ASP.NET Core BlazorSignalR ガイダンス」のガイダンスをご覧ください。
スタンドアロンの Blazor WebAssembly や非ブラウザー アプリなど、プリレンダリングを使わないクライアント プロジェクト コンポーネントでは、次の例に示すように、ハブ接続へのアクセス トークンを指定します。 詳細については、「ASP.NET Core の認証と承認SignalR」を参照してください。
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject IAccessTokenProvider TokenProvider
@inject NavigationManager Navigation
...
var tokenResult = await TokenProvider.RequestAccessToken();
if (tokenResult.TryGetToken(out var token))
{
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/chathub"),
options => { options.AccessTokenProvider = () => Task.FromResult(token?.Value); })
.Build();
...
}
ログ機能
このセクションは、.NET 7 以降の ASP.NET Core の Blazor WebAssembly アプリに適用されます。
デバッグまたはトレース ログを有効にするには、記事「ASP.NET Core Blazor のログ」のバージョン 7.0 以降の「認証ログ (Blazor WebAssembly)」セクションを参照してください。
WebAssembly サンドボックス
WebAssembly "サンドボックス" では、WebAssembly コードを実行するシステムの環境へのアクセスが制限されます (I/O サブシステム、システム ストレージとリソース、オペレーティング システムへのアクセスなど)。 WebAssembly コードとコードを実行するシステム間の分離により、WebAssembly がシステムにとって安全なコーディング フレームワークになります。 ただし、WebAssembly は、ハードウェア レベルでのサイドチャネル攻撃に対して脆弱です。 ハードウェア調達における通常の予防措置およびデュー デリジェンスと、ハードウェアへのアクセスに対する制限を設けることが該当します。
"WebAssembly は、Microsoftによって所有も管理もされていません。"
詳細については、次の W3C リソースを参照してください。
- WebAssembly: セキュリティ
- WebAssembly 仕様: セキュリティに関する考慮事項
- W3C WebAssembly コミュニティ グループ: フィードバックと問題: W3C WebAssembly コミュニティ グループのリンクは参考用として、WebAssembly のセキュリティに関する脆弱性とバグには継続的にパッチが適用され、多くの場合ブラウザーによって報告および対処されることを明らかにするためにのみ提供されています。 "Blazor に関するフィードバックやバグ レポートを W3C WebAssembly コミュニティ グループに送信しないでください。" Blazor に関するフィードバックは、Microsoft ASP.NET Core 製品ユニットに報告する必要があります。 Microsoft 製品ユニットが WebAssembly に関して根本的な問題が存在すると判断した場合、ユニットはその問題を W3C WebAssembly コミュニティ グループに報告するための適切な手順を実行します。
実装ガイダンス
この「概要」の記事では、特定のプロバイダーに対して Blazor WebAssembly アプリのユーザーを認証する方法について説明します。
スタンドアロン Blazor WebAssembly アプリ:
- OIDC プロバイダーと WebAssembly 認証ライブラリ向けの一般的なガイダンス
- Microsoft アカウント
- Microsoft Entra ID (ME-ID)
- Azure Active Directory (AAD) B2C
ホストされている Blazor WebAssembly アプリ:
構成に関するその他のガイダンスについては、次の記事を参照してください。
- ASP.NET Core Blazor WebAssembly のセキュリティに関するその他のシナリオ
- ASP.NET Core で Graph API を使用するBlazor WebAssembly
PKCE で承認コード フローを使用する
Microsoft identity プラットフォームの JavaScript 用 Microsoft 認証ライブラリ (MSAL) v2.0 以降では、Proof Key for Code Exchange (PKCE) を使用した認証コード フローおよび Blazor を含むシングルページ アプリケーション用のクロスオリジン リソース共有 (CORS) のサポートが提供されています。
Microsoft は、暗黙的な許可の使用をお勧めしていません。
詳細については、次のリソースを参照してください。
- MSAL での認証フローのサポート: 暗黙的な許可
- Microsoft identity プラットフォームと暗黙的な許可フロー: 認証コード フローを優先する
- Microsoft identity プラットフォームと OAuth 2.0 認証コード フロー
その他のリソース
- Microsoft identity プラットフォーム ドキュメント
- プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する
- 転送されたヘッダー ミドルウェアを使用した、プロキシ サーバーと内部ネットワークの間での HTTPS スキーム情報の保持。
- 追加のシナリオとユース ケース (手動スキーム構成を含む)、正しい要求ルーティングのための要求パスの変更、Linux および IIS 以外のリバース プロキシのための要求スキームの転送。
- 認証を使用したプリレンダリング
- WebAssembly: セキュリティ
- WebAssembly 仕様: セキュリティに関する考慮事項
ASP.NET Core