次の方法で共有


認証ライブラリを使用して、ASP.NET Core Blazor WebAssembly スタンドアロン アプリをセキュリティで保護する

注意

これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。

警告

このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。

重要

この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。

現在のリリースについては、この記事の .NET 9 バージョンを参照してください。

この記事では、Blazor WebAssembly 認証ライブラリを使用して、ASP.NET Core Blazor WebAssembly スタンドアロン アプリをセキュリティで保護する方法について説明します。

Blazor WebAssembly 認証ライブラリ (Authentication.js) は、Microsoft Authentication Library (MSAL、 msal.js) を介した Proof Key for Code Exchange (PKCE) 認可コード フローのみをサポートします。 他の許可フローを実装するには、MSAL ガイダンスにアクセスして MSAL を直接実装しますが、Blazor アプリに PKCE 以外の許可フローを使用することはサポートされておらず、推奨もされていません。

Microsoft Entra (ME-ID) と Azure Active Directory B2C (AAD B2C) のガイダンスについては、このトピックのガイダンスに従わないでください。 「Microsoft Entra ID を使用して、ASP.NET Core Blazor WebAssembly スタンドアロン アプリをセキュリティで保護する」または「Azure Active Directory B2C を使用して、ASP.NET Core Blazor WebAssembly スタンドアロン アプリをセキュリティで保護する」をご覧ください。

この記事を読んだ後の追加のセキュリティ シナリオの説明については、「ASP.NET Core Blazor WebAssembly のセキュリティに関するその他のシナリオ」を参照してください。

チュートリアル

このチュートリアルのサブセクションでは、次の方法について説明します。

  • アプリを登録します
  • Blazor アプリを作成する
  • アプリを実行する

アプリを登録します

IP のメンテナンス担当者が指定したガイダンスに従って、OpenID Connect (OIDC)Identity プロバイダー (IP) にアプリを登録します。

次の情報を記録しておきます。

  • 機関 (例: https://accounts.google.com/)。
  • アプリケーション (クライアント) ID (たとえば、2...7-e...q.apps.googleusercontent.com)。
  • 追加の IP 構成 (IP のドキュメントを参照)。

Note

IP では OIDC を使用する必要があります。 たとえば、Facebook の IP は OIDC に準拠しているプロバイダーではないため、このトピックのガイダンスは Facebook IP では機能しません。 詳しくは、「ASP.NET Core Blazor WebAssembly をセキュリティで保護する」をご覧ください。

Blazor アプリを作成する

Microsoft.AspNetCore.Components.WebAssembly.Authentication ライブラリを使用するスタンドアロンBlazor WebAssembly アプリを作成するには、選択したツールのガイダンスに従ってください。 認証のサポートを追加する場合は、アプリの設定と構成に関するガイダンスについて、この記事の「アプリのパーツ」セクションを参照してください。

認証メカニズムを使用して新しい Blazor WebAssembly プロジェクトを作成するには:

Blazor WebAssembly アプリ テンプレートを選んだ後、[認証の種類][個別のアカウント] に設定します。

Blazor WebAssembly アプリ テンプレートを選んだ後、[認証の種類][個別のアカウント] に設定します。 [ASP.NET Core でホストされた] チェックボックスがオフになっていることを確認します。

[個別のアカウント] を選ぶと、ASP.NET Core の Identity システムが使われます。 この選択によって認証のサポートが追加されます。ユーザーがデータベースに保存されることはありません。 この記事の以降のセクションで詳細について説明します。

Configure the app

IP のガイダンスに従ってアプリを構成します。 少なくとも、アプリでは、その wwwroot/appsettings.json ファイル内に Local:Authority および Local:ClientId の構成設定が必要です。

{
  "Local": {
    "Authority": "{AUTHORITY}",
    "ClientId": "{CLIENT ID}"
  }
}

ポート 5001 の localhost アドレス上で実行されるアプリの Google OAuth 2.0 OIDC の例:

{
  "Local": {
    "Authority": "https://accounts.google.com/",
    "ClientId": "2...7-e...q.apps.googleusercontent.com",
    "PostLogoutRedirectUri": "https://localhost:5001/authentication/logout-callback",
    "RedirectUri": "https://localhost:5001/authentication/login-callback",
    "ResponseType": "code"
  }
}

リダイレクト URI (https://localhost:5001/authentication/login-callback) は、Google APIs コンソール[Credentials](認証情報)>{NAME}>[Authorized redirect URIs](承認されたリダイレクト URI) を使用して登録します。ここで、{NAME} は、Google APIs コンソールの OAuth 2.0 クライアント ID アプリの一覧にあるアプリのクライアント名です。

Note

OAuth 2.0 仕様に従っている一部の OIDC IP については、localhost リダイレクト URI 用にポート番号を指定する必要はありません。 一部の IP では、ループバック アドレスのリダイレクト URI でポートを省略できます。 その他、ポート番号にワイルドカードを使用できるものもあります (例: *)。 詳細については、IP のドキュメントを参照してください。

アプリを実行する

アプリを実行するには、次のいずれかの方法を使用します。

  • Visual Studio
    • [実行] ボタンを選択します。
    • メニューの、 [デバッグ]>[デバッグ開始] を使用します。
    • F5キーを押します。
  • .NET CLI コマンド シェル: アプリのフォルダーから dotnet watch (または dotnet run) コマンドを実行します。

アプリのパーツ

このセクションでは、Blazor WebAssembly プロジェクト テンプレートから生成されたアプリのパーツについて、アプリの構成方法を説明します。 「チュートリアル」セクションのガイダンスを使用してアプリを作成した場合、基本的な作業アプリケーションについては、このセクションに従う必要がある具体的なガイダンスはありません。 このセクションのガイダンスは、ユーザーの認証と承認を行うためにアプリを更新する場合に役立ちます。 ただし、アプリは別の方法で更新することもできます。それには、「チュートリアル」セクションに記載のガイダンスに従って新しいアプリを作成し、アプリのコンポーネント、クラス、リソースを新しいアプリに移動してください。

認証パッケージ

個人のユーザー アカウントを使用するようにアプリを作成すると、アプリは Microsoft.AspNetCore.Components.WebAssembly.Authentication パッケージのパッケージ参照を自動的に受け取ります。 このパッケージには、アプリでユーザーを認証し、保護された API を呼び出すためのトークンを取得するのに役立つ一連のプリミティブが用意されています。

アプリに認証を追加する場合は、アプリに Microsoft.AspNetCore.Components.WebAssembly.Authentication パッケージを手動で追加します。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。

認証サービスのサポート

OpenID Connect (OIDC) を使用したユーザーの認証のサポートは、Microsoft.AspNetCore.Components.WebAssembly.Authentication パッケージによって提供される AddOidcAuthentication 拡張メソッドでサービス コンテナーに登録されます。

AddOidcAuthentication メソッドでは、OIDC を使用してアプリを認証するために必要なパラメーターを構成するためのコールバックを受け入れます。 アプリの構成に必要な値は、OIDC に準拠する IP から取得できます。 アプリを登録するときに値を取得します。これは通常、オンライン ポータルで実行されます。

新しいアプリの場合は、次の構成で {AUTHORITY}{CLIENT ID} のプレースホルダーに値を指定します。 アプリの IP での使用に必要なその他の構成値を指定します。 この例は Google 用であり、PostLogoutRedirectUriRedirectUriResponseType が必要です。 アプリに認証を追加する場合は、次のコードと構成を、プレースホルダーの値とその他の構成値を指定して、アプリに手動で追加します。

Program ファイルで次の操作を行います。

builder.Services.AddOidcAuthentication(options =>
{
    builder.Configuration.Bind("Local", options.ProviderOptions);
});

wwwroot/appsettings.json 構成

構成は wwwroot/appsettings.json ファイルによって提供されます。

{
  "Local": {
    "Authority": "{AUTHORITY}",
    "ClientId": "{CLIENT ID}"
  }
}

アクセス トークン スコープ

Blazor WebAssembly テンプレートでは、openidprofile の既定のスコープが自動的に構成されます。

Blazor WebAssembly テンプレートでは、セキュリティで保護された API のアクセス トークンを要求するようにアプリが自動的に構成されるわけではありません。 サインイン フローの一部としてアクセス トークンをプロビジョニングするには、OidcProviderOptions の既定のトークン スコープにスコープを追加します。 アプリに認証を追加する場合は、次のコードを手動で追加し、スコープ URI を構成します。

Program ファイルで次の操作を行います。

builder.Services.AddOidcAuthentication(options =>
{
    ...
    options.ProviderOptions.DefaultScopes.Add("{SCOPE URI}");
});

詳細については、"その他のシナリオ" に関する記事の次のセクションを参照してください。

インポート ファイル

Microsoft.AspNetCore.Components.Authorization 名前空間は、_Imports.razor ファイルを介してアプリ全体で使用できるようになります。

@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using {APPLICATION ASSEMBLY}
@using {APPLICATION ASSEMBLY}.Shared

Index ページ

Index ページ (wwwroot/index.html) ページには、JavaScript で AuthenticationService を定義するスクリプトが含まれています。 AuthenticationService によって、OIDC プロトコルの下位レベルの詳細が処理されます。 アプリは、認証操作を実行するために、スクリプトで定義されているメソッドを内部的に呼び出します。

<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>

アプリ コンポーネント

App コンポーネント (App.razor) は、Blazor Server アプリにある App コンポーネントに似ています。

  • AuthorizeRouteView コンポーネントによって、現在のユーザーには所与のページへのアクセスが許可されます。それ以外では、RedirectToLogin コンポーネントがレンダリングされます。
  • RedirectToLogin コンポーネントによって、承認されていないユーザーのログイン ページへのリダイレクトが管理されます。
  • CascadingAuthenticationState コンポーネントによって、アプリの rest に AuthenticationState を公開する動作が管理されます。
  • AuthorizeRouteView コンポーネントによって、現在のユーザーには所与のページへのアクセスが許可されます。それ以外では、RedirectToLogin コンポーネントがレンダリングされます。
  • RedirectToLogin コンポーネントによって、承認されていないユーザーのログイン ページへのリダイレクトが管理されます。

ASP.NET Core のリリースごとにフレームワークに違いがあるため、App コンポーネント (App.razor) の Razor マークアップは、このセクションでは説明しません。 特定のリリース向けのコンポーネントのマークアップを調べる場合は、次の方法の ''いずれか'' を使用してください。

  • 使用しようとしている ASP.NET Core のバージョン向けの既定の Blazor WebAssembly プロジェクト テンプレートから、認証のためにプロビジョニングされたアプリを作成します。 作成されたアプリで、App コンポーネント (App.razor) を検証します。

  • 参照元 で、App コンポーネント (App.razor) を検証します。 ブランチ セレクターからバージョンを選択し、リポジトリの ProjectTemplates フォルダーでコンポーネントを検索します。これは、長年にわたって移動しているためです。

    Note

    通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。

RedirectToLogin コンポーネント

RedirectToLogin コンポーネント (RedirectToLogin.razor) は:

  • 承認されていないユーザーのログイン ページへのリダイレクトを管理します。
  • ユーザーがアクセスしようとしている現在の URL は、次を使用して認証が成功した場合にそのページに戻ることができるように保持されます。

参照元で、RedirectToLogin コンポーネントを検証します。 コンポーネントの場所は時間の経過と共に変更されたため、GitHub 検索ツールを使用してコンポーネントを見つけてください。

Note

通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。

LoginDisplay コンポーネント

LoginDisplay コンポーネント (LoginDisplay.razor) は MainLayout コンポーネント (MainLayout.razor) でレンダリングされます。このコンポーネントによって次の動作が管理されます。

  • 認証されたユーザーの場合:
    • 現在のユーザー名が表示されます。
    • ASP.NET Core Identity のユーザー プロファイル ページへのリンクが提供されます。
    • アプリからログアウトするためのボタンが用意されます。
  • 匿名ユーザーの場合:
    • 登録するオプションが提供されます。
    • ログインするオプションが提供されます。

ASP.NET Core のリリースごとにフレームワークに違いがあるため、LoginDisplay コンポーネントの Razor マークアップは、このセクションでは説明しません。 特定のリリース向けのコンポーネントのマークアップを調べる場合は、次の方法の ''いずれか'' を使用してください。

  • 使用しようとしている ASP.NET Core のバージョン向けの既定の Blazor WebAssembly プロジェクト テンプレートから、認証のためにプロビジョニングされたアプリを作成します。 作成されたアプリで、LoginDisplay コンポーネントを検証します。

  • 参照元で、LoginDisplay コンポーネントを検証します。 コンポーネントの場所は時間の経過と共に変更されたため、GitHub 検索ツールを使用してコンポーネントを見つけてください。 true と等しい Hosted のテンプレート コンテンツが使用されます。

    注意

    通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。

認証コンポーネント

Authentication コンポーネント (Pages/Authentication.razor) によって生成されるページによって、さまざまな認証ステージを処理するために必要なルートが定義されます。

RemoteAuthenticatorView コンポーネント:

@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication

<RemoteAuthenticatorView Action="@Action" />

@code {
    [Parameter]
    public string? Action { get; set; }
}

Note

null 許容参照型 (NRT) と .NET コンパイラの null 状態スタティック分析は、.NET 6 以降の ASP.NET Core でサポートされています。 .NET 6 の ASP.NET Core のリリースより前は、string 型は null 型の指定 (?) なしで表示されます。

トラブルシューティング

ログ機能

Blazor WebAssembly 認証のデバッグまたはトレース ログを有効にするには、記事バージョン セレクターを ASP.NET Core 7.0 以降に設定して、ASP.NET Core Blazor ログの "クライアント側認証ログ" セクションを参照してください。

一般的なエラー

  • アプリまたは Identity プロバイダー (IP) の構成の誤り

    最も一般的なエラーの原因は、構成の誤りです。 以下に例を示します。

    • シナリオの要件によっては、権限、インスタンス、テナント ID、テナント ドメイン、クライアント ID、またはリダイレクト URI の欠落または誤りによって、アプリによるクライアントの認証ができなくなります。
    • 要求スコープが正しくないと、クライアントはサーバー Web API エンドポイントにアクセスできません。
    • サーバー API のアクセス許可が正しくないか、存在しないと、クライアントがサーバー Web API エンドポイントにアクセスできなくなります。
    • IP のアプリ登録のリダイレクト URI で構成されているものとは異なるポートでアプリが実行されています。 Microsoft Entra ID と、localhost 開発テスト アドレスで実行されるアプリにポートは必要ありませんが、アプリのポート構成とアプリが実行されているポートは、localhost 以外のアドレスと一致する必要があることに注意してください。

    この記事のガイダンスの構成セクションに、正しい構成の例を示します。 記事の各セクションを慎重に確認して、アプリと IP の構成の誤りを探してください。

    構成が正しい場合:

    • アプリケーション ログを分析します。

    • ブラウザーの開発者ツールを使用して、クライアント アプリと IP またはサーバー アプリの間のネットワーク トラフィックを確認します。 多くの場合、要求を行った後、IP またはサーバー アプリによって、問題の原因を特定する手掛かりを含む正確なエラー メッセージまたはメッセージがクライアントに返されます。 開発者ツールのガイダンスは、次の記事にあります。

    • JSON Web トークン (JWT) が使われている Blazor のリリースの場合は、問題が発生している場所に応じて、クライアントの認証またはサーバー Web API へのアクセスに使われるトークンの内容をデコードします。 詳細については、「JSON Web トークン (JWT) の内容を検査する」を参照してください。

    ドキュメント チームは、ドキュメントのフィードバックと記事のバグについては対応します (こちらのページのフィードバック セクションからイシューを作成してください) が、製品サポートを提供することはできません。 アプリのトラブルシューティングに役立つ、いくつかのパブリック サポート フォーラムが用意されています。 次をお勧めします。

    上記のフォーラムは、Microsoft が所有または管理するものではありません。

    セキュリティで保護されておらず、機密でも社外秘でもない再現可能なフレームワークのバグ レポートについては、ASP.NET Core 製品単位でイシューを作成してください。 問題の原因を徹底的に調査し、パブリック サポート フォーラムのコミュニティの助けを借りてもお客様自身で解決できない場合にのみ、製品単位でイシューを作成してください。 単純な構成の誤りやサードパーティのサービスに関連するユース ケースによって破損した個々のアプリのトラブルシューティングは、製品単位で行うことはできません。 レポートが機密性の高い性質のものである場合や、攻撃者が悪用するおそれのある製品の潜在的なセキュリティ上の欠陥が記述されている場合は、「セキュリティの問題とバグの報告」 (dotnet/aspnetcore GitHub リポジトリ) をご覧ください。

  • ME-ID で承認されないクライアント

    情報:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] 承認に失敗しました。 次の要件が満たされていません。DenyAnonymousAuthorizationRequirement:認証済みユーザーが必要です。

    ME-ID からのログイン コールバック エラー:

    • エラー: unauthorized_client
    • 説明: AADB2C90058: The provided application is not configured to allow public clients.

    このエラーを解決するには:

    1. Azure portal で、アプリのマニフェストにアクセスします。
    2. allowPublicClient 属性null または true に設定します。

Cookie とサイト データ

Cookie とサイト データは、アプリが更新されても保持され、テストやトラブルシューティングに影響する可能性があります。 アプリ コードの変更、プロバイダーによるユーザー アカウントの変更、プロバイダー アプリの構成変更を行うときは、次のものをクリアしてください。

  • ユーザーのサインインの Cookie
  • アプリの Cookie
  • キャッシュおよび保存されたサイト データ

残った Cookie とサイト データがテストとトラブルシューティングに影響しないようにする方法を、次に示します。

  • ブラウザーを構成する
    • ブラウザーが閉じるたびに cookie とサイト データをすべて削除するように構成できることをテストするために、ブラウザーを使用します。
    • アプリ、テスト ユーザー、プロバイダー構成が変更されるたびにブラウザーが手動で、または IDE によって閉じられていることを確認します。
  • カスタム コマンドを使用して、Visual Studio でブラウザーを InPrivate または Incognito モードで開きます:
    • Visual Studio の [実行] ボタンをクリックして [ブラウザーの選択] ダイアログボックスを開きます。
    • [追加] ボタンを選びます。
    • [プログラム] フィールドでブラウザーのパスを指定します。 次の実行可能パスが、Windows 10 の一般的なインストール場所です。 ブラウザーが別の場所にインストールされている場合、または Windows 10 を使用していない場合は、ブラウザーの実行可能ファイルのパスを指定してください。
      • Microsoft Edge: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
      • Google Chrome: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
      • Mozilla Firefox: C:\Program Files\Mozilla Firefox\firefox.exe
    • [引数] フィールドに、ブラウザーを InPrivate または Incognito モードで開くために使用するコマンドライン オプションを指定します。 ブラウザーによっては、アプリの URL が必要になる場合があります。
      • Microsoft Edge:-inprivate を使用してください。
      • Google Chrome: --incognito --new-window {URL} を使用します。プレースホルダー {URL} は開く URL (たとえば、https://localhost:5001 など) です。
      • Mozilla Firefox: -private -url {URL} を使用します。プレースホルダー {URL} は開く URL (たとえば、https://localhost:5001 など) です。
    • [フレンドリ名] フィールドに名前を指定します。 たとえば、Firefox Auth Testing のようにします。
    • [OK] ボタンを選択します。
    • アプリでテストを繰り返すたびにブラウザー プロファイルを選択する必要がないようにするには、 [既定値として設定] ボタンでプロファイルを既定値として設定します。
    • アプリ、テスト ユーザー、またはプロバイダー構成が変更されるたびに、ブラウザーが IDE によって閉じられていることを確認します。

アプリのアップグレード

開発マシンで .NET Core SDK をアップグレードしたり、アプリ内のパッケージ バージョンを変更したりした直後に、機能しているアプリが失敗することがあります。 場合によっては、パッケージに統一性がないと、メジャー アップグレード実行時にアプリが破壊されることがあります。 これらの問題のほとんどは、次の手順で解決できます。

  1. コマンド シェルから dotnet nuget locals all --clear を実行して、ローカル システムの NuGet パッケージ キャッシュをクリアします。
  2. プロジェクトのフォルダー binobj を削除します。
  3. プロジェクトを復元してリビルドします。
  4. アプリを再展開する前に、サーバー上の展開フォルダー内のすべてのファイルを削除します。

Note

アプリのターゲット フレームワークと互換性のないパッケージ バージョンの使用はサポートされていません。 パッケージの詳細については、NuGet ギャラリーまたは FuGet パッケージ エクスプローラーを使用してください。

Server アプリを実行する

ホステッド Blazor WebAssemblyソリューションのテストとトラブルシューティングを行うときは、Server プロジェクトからアプリを実行していることをご確認ください。

ユーザーを検査する

次の User コンポーネントは、アプリ内で直接使うことも、さらにカスタマイズするための基礎として使うこともできます。

User.razor:

@page "/user"
@attribute [Authorize]
@using System.Text.Json
@using System.Security.Claims
@inject IAccessTokenProvider AuthorizationService

<h1>@AuthenticatedUser?.Identity?.Name</h1>

<h2>Claims</h2>

@foreach (var claim in AuthenticatedUser?.Claims ?? Array.Empty<Claim>())
{
    <p class="claim">@(claim.Type): @claim.Value</p>
}

<h2>Access token</h2>

<p id="access-token">@AccessToken?.Value</p>

<h2>Access token claims</h2>

@foreach (var claim in GetAccessTokenClaims())
{
    <p>@(claim.Key): @claim.Value.ToString()</p>
}

@if (AccessToken != null)
{
    <h2>Access token expires</h2>

    <p>Current time: <span id="current-time">@DateTimeOffset.Now</span></p>
    <p id="access-token-expires">@AccessToken.Expires</p>

    <h2>Access token granted scopes (as reported by the API)</h2>

    @foreach (var scope in AccessToken.GrantedScopes)
    {
        <p>Scope: @scope</p>
    }
}

@code {
    [CascadingParameter]
    private Task<AuthenticationState> AuthenticationState { get; set; }

    public ClaimsPrincipal AuthenticatedUser { get; set; }
    public AccessToken AccessToken { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        var state = await AuthenticationState;
        var accessTokenResult = await AuthorizationService.RequestAccessToken();

        if (!accessTokenResult.TryGetToken(out var token))
        {
            throw new InvalidOperationException(
                "Failed to provision the access token.");
        }

        AccessToken = token;

        AuthenticatedUser = state.User;
    }

    protected IDictionary<string, object> GetAccessTokenClaims()
    {
        if (AccessToken == null)
        {
            return new Dictionary<string, object>();
        }

        // header.payload.signature
        var payload = AccessToken.Value.Split(".")[1];
        var base64Payload = payload.Replace('-', '+').Replace('_', '/')
            .PadRight(payload.Length + (4 - payload.Length % 4) % 4, '=');

        return JsonSerializer.Deserialize<IDictionary<string, object>>(
            Convert.FromBase64String(base64Payload));
    }
}

JSON Web トークン (JWT) の内容を検査する

JSON Web トークン (JWT) をデコードするには、Microsoft の jwt.ms ツールを使用します。 UI の値がブラウザーに残ることはありません。

エンコードされた JWT の例 (表示用に短縮されています):

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1j ... bQdHBHGcQQRbW7Wmo6SWYG4V_bU55Ug_PW4pLPr20tTS8Ct7_uwy9DWrzCMzpD-EiwT5IjXwlGX3IXVjHIlX50IVIydBoPQtadvT7saKo1G5Jmutgq41o-dmz6-yBMKV2_nXA25Q

Azure AAD B2C に対して認証するアプリのツールによってデコードされた JWT の例:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"
}.{
  "exp": 1610059429,
  "nbf": 1610055829,
  "ver": "1.0",
  "iss": "https://mysiteb2c.b2clogin.com/11112222-bbbb-3333-cccc-4444dddd5555/v2.0/",
  "sub": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
  "aud": "00001111-aaaa-2222-bbbb-3333cccc4444",
  "nonce": "bbbb0000-cccc-1111-dddd-2222eeee3333",
  "iat": 1610055829,
  "auth_time": 1610055822,
  "idp": "idp.com",
  "tfp": "B2C_1_signupsignin"
}.[Signature]

その他の技術情報