Azure AD B2C を使用して Web API を呼び出すサンプルの Web アプリで認証を構成する

この記事では、Web API を呼び出すサンプルの ASP.NET Web アプリケーションを使用して、Web アプリケーションに Azure Active Directory B2C (Azure AD B2C) 認証を追加する方法を説明します。

重要

この記事で参照されているサンプルの ASP.NET Web アプリは、ベアラー トークンを使用して Web API を呼び出すために使用されます。 Web API を呼び出さない Web アプリケーションについては、「Azure AD B2C を使用してサンプル Web アプリで認証を構成する」を参照してください。

概要

OpenID Connect (OIDC) は、OAuth 2.0 を基盤にした認証プロトコルです。 OIDC を使用して、ユーザーをアプリケーションに安全にサインインさせることができます。 この Web アプリのサンプルでは、Microsoft Identity Web が使用されます。 Microsoft Identity Web は、セキュリティ保護された Web API を呼び出すことができる Web アプリへの認証と認可のサポートの追加を簡略化する ASP.NET Core ライブラリのセットです。

サインイン フローでは、次の手順が実行されます。

  1. ユーザーが Web アプリにアクセスして [サインイン] を選択します。

  2. アプリによって認証要求が開始され、ユーザーが Azure AD B2C にリダイレクトされます。

  3. ユーザーがサインアップまたはサインインし、パスワードをリセットします。 ソーシャル アカウントを使用してサインインすることもできます。

  4. ユーザーがサインインすると、Azure AD B2C からアプリに認可コードが返されます。

  5. その後、アプリでは次が実行されます。

    a. 認可コードが、ID トークン、アクセス トークン、更新トークンと交換されます。
    b. ID トークン クレームが読み取られて、アプリケーション認可 Cookie が永続化されます。
    c. 後で使用できるように、更新トークンがメモリ内キャッシュに格納されます。

アプリ登録の概要

アプリで Azure AD B2C を使用してサインインし、Web API を呼び出せるようにするには、Azure AD B2C ディレクトリに 2 つのアプリケーションを登録します。

  • Web アプリケーションの登録により、アプリでは Azure AD B2C を使用してサインインできるようになります。 登録時に、"リダイレクト URI" を指定します。 リダイレクト URI は、Azure AD B2C での認証が完了した後にユーザーが Azure AD B2C によってリダイレクトされるエンドポイントです。 アプリの登録プロセスによって、アプリを一意に識別する "アプリケーション ID" ("クライアント ID" とも呼ばれます) が生成されます。 また、トークンを安全に取得するためにアプリによって使用される、"クライアント シークレット" を作成します。

  • Web API の登録により、アプリではセキュリティで保護された Web API を呼び出すことができます。 登録には、Web API の "スコープ" が含まれます。 スコープを使用することで、Web API などの保護されたリソースへのアクセス許可を管理できます。 Web アプリケーションのアクセス許可を Web API のスコープに付与します。 アクセス トークンが要求されたら、アプリで必要なアクセス許可を要求の scope パラメーターに指定します。

アプリのアーキテクチャと登録について、次の図に示します。

Diagram of a web app with web API call registrations and tokens.

Web API の呼び出し

認証が完了した後、ユーザーがアプリと対話すると、保護された Web API が呼び出されます。 その Web API では、ベアラー トークン認証が使用されます。 ベアラー トークンは、アプリによって Azure AD B2C から取得されたアクセス トークンです。 アプリでは、HTTPS 要求の Authorization ヘッダーでトークンを渡します。

Authorization: Bearer <access token>

アクセス トークンのスコープが Web API のスコープと一致しない場合、認証ライブラリでは正しいスコープの新しいアクセス トークンが取得されます。

サインアウト

サインアウト フローには、次の手順が含まれます。

  1. アプリから、ユーザーがサインアウトします。
  2. アプリによってそのセッション オブジェクトがクリアされ、認証ライブラリによってそのトークン キャッシュがクリアされます。
  3. アプリによってユーザーが Azure AD B2C サインアウト エンドポイントに移動し、Azure AD B2C セッションが終了されます。
  4. ユーザーが再びアプリにリダイレクトされます。

前提条件

次のいずれかを実行しているコンピューター:

手順 1: ユーザー フローを構成する

ユーザーがアプリにサインインしようとすると、ユーザー フローを介した承認エンドポイントへの認証要求がアプリによって開始されます。 ユーザー フローによって、ユーザーのエクスペリエンスが定義および制御されます。 ユーザーがユーザー フローを完了すると、Azure AD B2C によってトークンが生成され、ユーザーはアプリケーションにリダイレクトされます。

ユーザー フローまたはカスタム ポリシーの作成をまだ行っていない場合は、作成します。 手順を繰り返して、次のように 3 つの個別のユーザー フローを作成します。

  • サインインと サインアップを結合したユーザー フロー (例:)susi。 このユーザー フローでは、パスワードを忘れた 場合のエクスペリエンスもサポート されています。
  • プロファイル編集 ユーザー フロー (例: edit_profile) 。
  • パスワードのリセット ユーザー フロー (例: reset_password)。

Azure AD B2C は、 B2C_1_ ユーザー フロー名の前に付加されます。 たとえば、susiB2C_1_susi になります。

手順 2: Web アプリケーションを登録する

この手順では、Web アプリと Web API アプリケーションの登録を作成し、Web API のスコープを指定します。

手順 2.1: Web API アプリを登録する

Web API アプリの登録 (App ID: 2) を作成するには、次の手順に従います。

  1. Azure portal にサインインします。

  2. ご自分の Azure AD B2C テナントが含まれるディレクトリを必ず使用してください。 ポータル ツールバーの [Directories + subscriptions](ディレクトリ + サブスクリプション) アイコンを選択します。

  3. [ポータルの設定] | [Directories + subscriptions](ディレクトリ + サブスクリプション) ページの [ディレクトリ名] の一覧で自分の Azure AD B2C ディレクトリを見つけて、 [切り替え] を選択します。

  4. Azure portal で、 [Azure AD B2C] を検索して選択します。

  5. [アプリの登録] を選択し、 [新規登録] を選択します。

  6. アプリケーションの名前を入力します (my-api1 など)。 [リダイレクト URI][サポートされているアカウントの種類] を既定値のままにします。

  7. [登録] を選択します。

  8. アプリ登録が完了したら、 [概要] を選択します。

  9. アプリケーション (クライアント) ID の値を記録しておきます。これは、後で Web アプリケーションを構成するときに使用します。

    Screenshot that demonstrates how to get a web A P I application I D.

手順 2.2: Web API アプリのスコープを構成する

  1. 作成した my-api1 アプリケーション (App ID: 2) を選択して、その [概要] ページを開きます。

  2. [管理][API の公開] を選択します。

  3. [アプリケーション ID URI] の横にある [設定] リンクを選択します。 既定値 (GUID) を一意の名前 (例: tasks-api) に置き換え、[保存] を選択します。

    Web アプリケーションで Web API のアクセス トークンを要求するときに、API に対して定義する各スコープのプレフィックスとしてこの URI を追加する必要があります。

  4. [この API で定義されるスコープ] で、 [スコープの追加] を選択します。

  5. API への読み取りアクセスを定義するスコープを作成するには:

    1. [スコープ名]tasks.read を入力します。
    2. [管理者の同意の表示名] で、「Read access to tasks API」を入力します。
    3. [管理者の同意の説明] で、「Allows read access to the tasks API」を入力します。
  6. [スコープの追加] を選択します。

  7. [Add a scope (スコープの追加)] を選択し、API への書き込みアクセスを定義するスコープを追加します。

    1. [スコープ名] に「tasks.write」を入力します。
    2. [管理者の同意の表示名] に、「Write access to tasks API」を入力します。
    3. [管理者の同意の説明] に、「Allows write access to the tasks API」を入力します。
  8. [スコープの追加] を選択します。

手順 2.3: Web アプリを登録する

Web アプリの登録を作成するには、次の手順を実行します。

  1. [アプリの登録] を選択し、 [新規登録] を選択します。

  2. [名前] で、アプリケーションの名前を入力します (webapp1 など)。

  3. [サポートされているアカウントの種類] で、 [Accounts in any identity provider or organizational directory (for authenticating users with user flows)]((ユーザー フローを使用してユーザーを認証するための) 任意の ID プロバイダーまたは組織のディレクトリのアカウント) を選択します。

  4. [リダイレクト URI] で、 [Web] を選択し、URL ボックスに「https://localhost:5000/signin-oidc」と入力します。

  5. [アクセス許可] で、 [Grant admin consent to openid and offline access permissions](OpenID とオフラインのアクセス許可に管理者の同意を与える) チェック ボックスをオンにします。

  6. [登録] を選択します。

  7. アプリ登録が完了したら、 [概要] を選択します。

  8. アプリケーション (クライアント) ID を記録しておきます。これは、後で Web アプリケーションを構成するときに使用します。

    Screenshot of the web app Overview page for recording your web application ID.

手順 2.4: Web アプリのクライアント シークレットを作成する

登録済み Web アプリケーションに対してクライアント シークレットを作成します。 Web アプリケーションでは、トークンを要求するときに、このクライアント シークレットを使ってその ID を証明します。

  1. [管理] で、[証明書とシークレット] を選択します。
  2. [新しいクライアント シークレット] を選択します。
  3. [説明] ボックスにクライアント シークレットの説明を入力します (例、clientsecret1)。
  4. [有効期限] で、シークレットが有効な期間を選択してから、 [追加] を選択します。
  5. シークレットのを記録します。 この値は、後の手順での構成に使用します。

手順 2.5: Web API に対するアクセス許可を Web アプリに付与する

アプリ (アプリ ID: 1) にアクセス許可を付与するには、次の手順をおこないます。

  1. [アプリの登録] を選択し、作成したアプリを選択します (アプリ ID: 1)。

  2. [管理] の下にある [API のアクセス許可] を選択します。

  3. [構成されたアクセス許可] の下で [アクセス許可の追加] を選択します。

  4. [自分の API] タブを選択します。

  5. Web アプリケーションへのアクセス許可が必要な API を選択します (アプリ ID: 2)。 たとえば、「my-api1」と入力します。

  6. [アクセス許可] で、 [タスク] を展開し、前に定義したスコープを選択します(たとえば、tasks.readtasks.write)。

  7. [アクセス許可の追加] を選択します.

  8. [<テナント名> に管理者の同意を与えます] を選択します。

  9. [はい] を選択します。

  10. [最新の情報に更新] を選択し、両方のスコープの [状態] に、Granted for ...(... に付与されました) と表示されていることを確認します。

  11. [Configured permissions (構成済みのアクセス許可)] の一覧からスコープを選択し、スコープの完全な名前をコピーします。

    Screenshot of the configured permissions pane, showing that read access permissions are granted.

手順 3: Web アプリのサンプルを取得する

zip ファイルをダウンロードするか、次の Bash コマンドを実行して、GitHub からサンプル Web アプリケーションをクローンします。

git clone https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2

パスの合計文字長が 260 以下のフォルダーにサンプル ファイルを展開します。

手順 4: サンプル Web API を構成する

サンプル フォルダー内の 4-WebApp-your-API/4-2-B2C/TodoListService フォルダーにある TodoListService.csproj プロジェクトを Visual Studio または Visual Studio Code で開きます。

プロジェクトのルート フォルダーで、appsettings.json ファイルを開きます。 このファイルには、Azure AD B2C ID プロバイダーに関する情報が含まれています。 Web API アプリではこの情報を使用して、Web アプリからベアラー トークンとして渡されるアクセス トークンが検証されます。 アプリ設定の次のプロパティを更新します。

Section キー
AzureAdB2C インスタンス Azure AD B2C テナント名の最初の部分。 たとえば、「 https://contoso.b2clogin.com 」のように入力します。
AzureAdB2C Domain Azure AD B2C テナントの完全なテナント名。 たとえば、「 contoso.onmicrosoft.com 」のように入力します。
AzureAdB2C ClientId 手順 2.1 の Web API アプリケーション ID。
AzureAdB2C SignUpSignInPolicyId ユーザー フロー、または手順 1 で作成したカスタム ポリシー。

最終的な構成ファイルは、次の JSON ファイルのようになります。

{
  "AzureAdB2C": {
    "Instance": "https://contoso.b2clogin.com",
    "Domain": "contoso.onmicrosoft.com",
    "ClientId": "<web-api-app-application-id>",
    "SignedOutCallbackPath": "/signout/<your-sign-up-in-policy>",
    "SignUpSignInPolicyId": "<your-sign-up-in-policy>"
  },
  // More settings here
}

手順 4.1: アクセス許可ポリシーを設定する

Web API により、ユーザーがベアラー トークンを使用して認証されたこと、および構成された承認済みのスコープがベアラー トークンに設定されていることが検証されます。 ベアラー トークンにこれらの受け入れられたスコープが設定されていない場合、Web API により HTTP 状態コード 403 (禁止) が返され、トークンで想定されているスコープを示すメッセージが応答本文に書き込まれます。

受け入れられたスコープを構成するには、Controller/TodoListController.cs クラスを開き、スコープ名を完全な URI なしで設定します。

[RequiredScope("tasks.read")]

手順 4.2: サンプル Web API アプリを実行する

Web アプリで Web API サンプルが呼び出されるのを許可するには、次の手順に従って Web API を実行します。

  1. 要求されている場合は、依存関係を復元します。
  2. プロジェクトをビルドして実行します。
  3. プロジェクトがビルドされると、Visual Studio または Visual Studio Code により、アドレス https://localhost:44332. を使用してブラウザーで Web API が開始されます

手順 5: サンプル Web アプリを構成する

サンプル フォルダー内の 4-WebApp-your-API/4-2-B2C/Client フォルダーにある TodoListClient.csproj プロジェクトを Visual Studio または Visual Studio Code で開きます。

プロジェクト ルート フォルダーで、appsettings.json ファイルを開きます。 このファイルには、Azure AD B2C ID プロバイダーに関する情報が含まれています。 Web アプリでは、この情報を使用して Azure AD B2C との信頼関係を確立し、ユーザーのサインインとサインアウトを行い、トークンを取得して、それらを検証します。 アプリ設定の次のプロパティを更新します。

Section キー
AzureAdB2C インスタンス Azure AD B2C テナント名の最初の部分 (例: https://contoso.b2clogin.com)。
AzureAdB2C Domain Azure AD B2C テナントの完全なテナント名 (例: contoso.onmicrosoft.com)。
AzureAdB2C ClientId 手順 2.3 の Web アプリケーション ID。
AzureAdB2C ClientSecret 手順 2.4 の Web アプリケーション シークレット。
AzureAdB2C SignUpSignInPolicyId ユーザー フロー、または手順 1 で作成したカスタム ポリシー。
TodoList TodoListScope 手順 2.5 で作成した Web API スコープ。
TodoList TodoListBaseAddress Web API のベース URI (例: https://localhost:44332)。

最終的な構成ファイルは、次の JSON のようになります。

{
  "AzureAdB2C": {
    "Instance": "https://contoso.b2clogin.com",
    "Domain": "contoso.onmicrosoft.com",
    "ClientId": "<web-app-application-id>",
    "ClientSecret": "<web-app-application-secret>",  
    "SignedOutCallbackPath": "/signout/<your-sign-up-in-policy>",
    "SignUpSignInPolicyId": "<your-sign-up-in-policy>"
  },
  "TodoList": {
    "TodoListScope": "https://contoso.onmicrosoft.com/api/demo.read",
    "TodoListBaseAddress": "https://localhost:44332"
  }
}

手順 6: サンプル Web アプリを実行する

  1. プロジェクトをビルドして実行します。
  2. [http://.azurewebsites.net/admin](https://localhost:5000) を参照します。
  3. サインインアップまたはサインイン プロセスを完了します。

認証が成功すると、ナビゲーション バーに表示名が表示されます。 Azure AD B2C トークンによってアプリに返されるクレームを表示するには、 [TodoList] を選択します。

Screenshot of the web app token claims.

アプリケーションをデプロイする

運用アプリケーションでは、通常、アプリ登録のリダイレクト URI は、アプリが実行されているパブリックにアクセス可能なエンドポイント (https://contoso.com/signin-oidc など) です。

お使いの登録済みアプリケーションでは、いつでもリダイレクト URI を追加したり、変更したりすることができます。 リダイレクト URI には、次の制限があります。

  • 応答 URL は、スキーム https で始まる必要があります。
  • 応答 URL では大文字と小文字が区別されます。 大文字と小文字の区別は、実行中のアプリケーションの URL パスの場合と一致している必要があります。

Web アプリのトークン キャッシュ

Web アプリのサンプルでは、メモリ内のトークン キャッシュのシリアル化が使用されています。 この実装は、サンプルにおいて非常に有用です。 また、Web アプリの再起動時にトークン キャッシュが失われても構わない場合は、実稼働アプリケーションにも適しています。

運用環境では、分散メモリ キャッシュを使用することをお勧めします。 たとえば、Redis Cache、NCache、SQL Server キャッシュなどです。 分散メモリ キャッシュの実装の詳細については、「トークン キャッシュのシリアル化」を参照してください。

次の手順