リージョンベースの構成の Azure Active Directory B2C グローバル ID フレームワーク概念実証

次のセクションでは、リージョンベースのオーケストレーションの概念実証の実装を作成する方法について説明します。 完全な Azure Active Directory B2C (Azure AD B2C) カスタム ポリシーについては、こちらを参照してください。

リージョンベースのアプローチ

各リージョンの Azure AD B2C テナントには、次の機能を含む Azure AD B2C カスタム ポリシーが必要です。

サインアップ体験:

  • ユーザーのユーザー名、パスワード、その他の属性を収集する画面を表示する
  • ユーザーとリージョンのマッピング テーブルに対してクエリを実行して、ユーザーが既に存在する場合にサインアップを防止する
  • ローカル テナントにユーザー プロファイルを書き込む
  • ユーザーのユーザー名からリージョンへのマッピングをマッピング テーブルに書き込む
  • アプリケーションにトークンを発行する

サインイン体験:

  • ユーザー名とパスワードの画面を表示する
  • ユーザー名の検索を実行し、そのリージョンを返す
  • ローカル資格情報の検証またはテナント間の資格情報の検証を実行する
  • ローカル テナントから、またはテナント間呼び出しを使用してユーザー プロファイルを読み取る
  • アプリケーションにトークンを発行する

パスワード リセット体験:

  • 電子メール OTP を使用してユーザーの電子メールを検証する画面を表示する
  • ユーザー名の検索を実行し、そのリージョンを返す
  • 新しいパスワードを取得する画面を表示する
  • ローカル テナントまたはテナント間呼び出しを使用して、新しいパスワードを書き込む
  • アプリケーションにトークンを発行する

次のブロック図は、概念実証を示しています。 このガイダンスでは、Azure AD B2C テナントを構成する方法について説明します。 外部 API レイヤーと地域分散ルックアップ テーブルは、このガイドの一部として含まれていません。

リージョンベースのアプローチのブロック図を示すスクリーンショット

前提条件

  1. ビジネスでサポートする必要があるリージョンごとにテナントを作成します。 この概念実証には、少なくとも 2 つのテナントが必要です。

  2. テナントにカスタム ポリシーをデプロイします。

ストレージ レイヤーを準備する

ユーザーの電子メール、objectId、リージョンを格納できるストレージ レイヤーが必要です。 これにより、ユーザーがサインアップした場所を追跡してクエリを実行できます。 Azure Storage テーブルを使用して、このデータを保持できます。

API レイヤーを準備する

リージョンベースのアプローチを示すために、概念実証の一部として複数の API が使用されています。

ユーザーが既に存在するかどうかを確認する

サインアップ時に API を使用して、ユーザーが既にリージョンに存在するかどうかを判断します。

要求は次のようになります。

POST /doesUserExistInLookupTable HTTP/1.1
Host: yourapi.com
Content-Type: application/json

{
  email: bob@contoso.com
}

  • ユーザーが存在しない場合、応答は HTTP 200 になります。

  • ユーザーが存在する場合、応答は HTTP 409 になります。

ユーザーとリージョンのマッピングを記録する

API は、サインアップ中に使用され、ユーザーがサインアップしたリージョンを記録します。

要求は次のようになります。

POST /userToRegionLookup HTTP/1.1
Host: yourapi.com
Authorization Bearer: <token>
Content-Type: application/json

{
  "email": "bob@contoso.com"
}

  • ユーザーが存在する場合、応答は HTTP 200 になります。

  • ユーザーが存在する場合、応答は HTTP 409 になります。

ユーザーが存在するリージョンを返す

サインイン中に API を使用して、ユーザーがサインアップしたリージョンを特定します。 これは、テナント間認証を実行する必要があるかどうかを示します。

要求は次のようになります。

POST /userToRegionLookup HTTP/1.1
Host: yourapi.com
Authorization Bearer: <token>
Content-Type: application/json

{
  "email": "bob@contoso.com"
}

応答は、ユーザーが登録したリージョンと objectId を含む HTTP 200 になります。

{
  "objectId": "460f9ffb-8b6b-458d-a5a4-b8f3a6816fc2",
  "region": "APAC"  
}

ユーザーが存在しない場合、またはエラーが発生した場合、API の応答は HTTP 409 です。

テナント間でパスワードを書き込む

API は、パスワードをリセットする別のリージョンにユーザーの新しいパスワードを書き込むためにパスワードのリセット フロー中に使用されます。

要求は次のようになります。

POST /writePasswordCrossTenant HTTP/1.1
Host: yourapi.com
Authorization Bearer: <token>
Content-Type: application/json

{
  "objectId": "460f9ffb-8b6b-458d-a5a4-b8f3a6816fc2",
  "password": "some!strong123STRING"
}

応答は、プロセスが成功した場合は HTTP 200、エラーがある場合は HTTP 409 になります。

リージョンベースの Azure AD B2C の構成

次のセクションでは、Azure AD B2C テナントを準備して、ユーザーがサインアップしたリージョンを追跡し、必要に応じてテナント間認証またはパスワード リセットを実行します。

カスタム ポリシー構成をサインアップする

サインアップ中に、ユーザーが他のテナントに存在しないことを確認し、ユーザーのユーザー リージョン マッピングを外部テーブルに書き込む必要があります。

Azure AD B2C スターター パックの LocalAccountSignUpWithLogonEmail プロファイルを次のように変更します。

<TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
...
  <ValidationTechnicalProfiles>            
    <ValidationTechnicalProfile ReferenceId="REST-getTokenforExternalApiCalls" />
    <ValidationTechnicalProfile ReferenceId="REST-doesUserExistInLookupTable" />        
    <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
    <ValidationTechnicalProfile ReferenceId="REST-writeUserToRegionMapping" />
  </ValidationTechnicalProfiles>
  <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
</TechnicalProfile>

ValidationTechnicalProfiles では、次のロジックが実行されます。

  1. REST-getTokenforExternalApiCalls 技術プロファイルを使用して、保護された API エンドポイントを呼び出すトークンを取得します。

    • Microsoft Entra ベアラー トークンを使用して API を取得および保護するには、こちらのドキュメントに従います。
  2. セキュリティで保護された外部 REST API エンドポイントを使用して、ユーザーとリージョンのマッピングにユーザーが既に存在するかどうかを確認します。

    • この API 呼び出しは、すべてのサインアップの前に行われます。アップタイム要件を維持するために、この API に適切な負荷分散、回復性、フェールオーバー メカニズムがあることを確認しておくことが重要です。

    • 外部 REST API を使用してユーザーとリージョンのマッピングに対してクエリを実行する技術プロファイルの例を次に示します。

      <TechnicalProfile Id="REST-doesUserExistInLookupTable ">
      <DisplayName>User to Region lookup</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">https://myApi.com/doesUserExistInLookupTable</Item>
        <Item Key="AuthenticationType">Bearer</Item>
        <Item Key="UseClaimAsBearerToken">ext_Api_bearerToken</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AllowInsecureAuthInProduction">false</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="ext_Api_bearerToken" />
        <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="email" />
      </InputClaims>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
      </TechnicalProfile>
      
    • ユーザーが存在する場合、この API は HTTP 409 で応答し、画面に適切なエラー メッセージが表示されます。 ユーザーが存在しない場合は HTTP 200 で応答します。

  3. セキュリティで保護された外部 REST API エンドポイントを使用してユーザーとリージョンのマッピングを作成する

    • この API 呼び出しは、すべてのサインアップの前に行われます。アップタイム要件を維持するために、この API に適切な負荷分散、回復性、フェールオーバー メカニズムがあることを確認しておくことが重要です。

    • 外部 REST API を使用してユーザーとリージョンのマッピングを書き込む技術プロファイルの例を次に示します。

    <TechnicalProfile Id="REST-writeUserToRegionMapping">
    <DisplayName>User to Region lookup</DisplayName>
    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    <Metadata>
      <Item Key="ServiceUrl">https://myApi.com/writeUserToRegionMapping</Item>
      <Item Key="AuthenticationType">Bearer</Item>
      <Item Key="UseClaimAsBearerToken">ext_Api_bearerToken</Item>
      <Item Key="SendClaimsIn">Body</Item>
      <Item Key="AllowInsecureAuthInProduction">false</Item>
    </Metadata>
    <InputClaims>
      <InputClaim ClaimTypeReferenceId="ext_Api_bearerToken" />
      <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="email" />
      <InputClaim ClaimTypeReferenceId="region" DefaultValue="EMEA" />
      <InputClaim ClaimTypeReferenceId="objectId" />
    </InputClaims>
    <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
    ``` 
    
    

サインインのカスタム ポリシーの構成

サインイン中に、ユーザー プロファイルの場所を特定し、プロファイルが保存されている Azure AD B2C テナントに対してユーザーを認証する必要があります。

Azure AD B2C スターター パックの SelfAsserted-LocalAccountSignin-Email 技術プロファイルを変更して、ユーザーとリージョンの検索を実行し、ユーザーが到達したテナントのリージョンとは別のリージョンの場合、テナント間認証を実行します。 次のように ValidationTechnicalProfiles を更新します。

<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email">
...
  <ValidationTechnicalProfiles>
    <ValidationTechnicalProfile ReferenceId="REST-getTokenforExternalApiCalls" />
    <ValidationTechnicalProfile ReferenceId="REST-regionLookup" />
    <ValidationTechnicalProfile ReferenceId="login-NonInteractive">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
          <Value>user_region</Value>
          <Value>EMEA</Value>
          <Action>SkipThisValidationTechnicalProfile</Action>
        </Precondition>
      </Preconditions>
     <ValidationTechnicalProfile ReferenceId="REST-login-NonInteractive-APAC">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
          <Value>user_region</Value>
          <Value>APAC</Value>
          <Action>SkipThisValidationTechnicalProfile</Action>
        </Precondition>
      </Preconditions>
    </ValidationTechnicalProfile>
    <ValidationTechnicalProfile ReferenceId="REST-fetchUserProfile-APAC">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
          <Value>user_region</Value>
          <Value>APAC</Value>
          <Action>SkipThisValidationTechnicalProfile</Action>
        </Precondition>
      </Preconditions>
    </ValidationTechnicalProfile>
  </ValidationTechnicalProfiles>
  <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
</TechnicalProfile>

ユーザーが資格情報を送信すると、ValidationTechnicalProfiles によって次のロジックが実行されます。

  1. REST-getTokenforExternalApiCalls 技術プロファイルを使用して、保護された API エンドポイントを呼び出すトークンを取得します。

    • Microsoft Entra ベアラー トークンを使用して API を取得および保護するには、こちらのドキュメントに従います。
  2. セキュリティで保護された外部 REST API エンドポイントを使用してユーザーとリージョンのマッピングを検索する

    • この API 呼び出しは、すべてのサインアップの前に行われます。アップタイム要件を維持するために、この API に適切な負荷分散、回復性、フェールオーバー メカニズムがあることを確認しておくことが重要です。

    • 外部 REST API を使用してユーザーとリージョンのマッピングに対してクエリを実行する技術プロファイルの例を次に示します。

      <TechnicalProfile Id="REST-regionLookup">
        <DisplayName>User to Region lookup</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <Metadata>
          <Item Key="ServiceUrl">https://myApi.com/userToRegionLookup</Item>
          <Item Key="AuthenticationType">Bearer</Item>
          <Item Key="UseClaimAsBearerToken">ext_Api_bearerToken</Item>
          <Item Key="SendClaimsIn">Body</Item>
          <Item Key="AllowInsecureAuthInProduction">false</Item>
        </Metadata>
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="ext_Api_bearerToken" />
          <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="email" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="user_region" PartnerClaimType="region" />
          <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="objectId" />
        </OutputClaims>
        <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
      </TechnicalProfile>
      
  3. このテナントでサインアップしたユーザーの login-NonInteractive 技術プロファイルを使用して、ローカル アカウント認証を実行します。 これは、Azure AD B2C スターター パックに含まれる既定の技術プロファイルです。

  4. 条件付きで、各リージョンの REST-login-NonInteractive-[region] 技術プロファイルを介してテナント間認証を実行します。

    • これにより、ユーザーのホーム テナントから MS Graph API トークンも取得されます。 委任されたアクセス許可 (user.read) の MS Graph API へのアクセス許可を使用して、各リージョン テナントでネイティブ アプリの登録を行います。

    • 外部 REST API を介してユーザーとリージョンのマッピングを実行する技術プロファイルの例を次に示します。

      <TechnicalProfile Id="REST-login-NonInteractive-APAC">
        <DisplayName>non interactive authentication to APAC</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <Metadata>
          <Item Key="ServiceUrl">https://login.microsoftonline.com/yourAPACb2ctenant.onmicrosoft.com/oauth2/v2.0/token</Item>
          <Item Key="AuthenticationType">None</Item>
          <Item Key="SendClaimsIn">Form</Item>
          <Item Key="AllowInsecureAuthInProduction">true</Item>
        </Metadata>
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="apac_client_id" PartnerClaimType="client_id" DefaultValue="cf3f6898-9a79-426a-ba16-10e1a377c843" />
          <InputClaim ClaimTypeReferenceId="ropc_grant_type" PartnerClaimType="grant_type" DefaultValue="password" />
          <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="username" />
          <InputClaim ClaimTypeReferenceId="password" />
          <InputClaim ClaimTypeReferenceId="scope" DefaultValue="https://graph.microsoft.com/.default" AlwaysUseDefaultValue="true" />
          <InputClaim ClaimTypeReferenceId="nca" PartnerClaimType="nca" DefaultValue="1" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="ext_Api_bearerToken" PartnerClaimType="access_token" />
        </OutputClaims>
        <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
      </TechnicalProfile>
      
    • <yourb2ctenant>ServiceUrl を、認証の対象にする必要があるテナントに置き換えます。

    • アプリケーション登録の ApplicationId を使用して、入力要求 apac_client_idDefaultValue を設定します。

  5. 条件付きで、各リージョンの REST-fetchUserProfile-[region] 技術プロファイルを介して、テナント間 REST API 呼び出しを使用してユーザー プロファイルをフェッチします。

    • MS Graph API を介してユーザーのプロファイルを読み取る技術プロファイルの例を次に示します。

      <TechnicalProfile Id="REST-fetchUserProfile-APAC">
        <DisplayName>fetch user profile cross tenant</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <Metadata>
          <Item Key="ServiceUrl">https://graph.microsoft.com/beta/me</Item>
          <Item Key="AuthenticationType">Bearer</Item>
          <Item Key="UseClaimAsBearerToken">graph_bearerToken</Item>
          <Item Key="SendClaimsIn">Body</Item>
        </Metadata>
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="graph_bearerToken" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="id" />
          <OutputClaim ClaimTypeReferenceId="givenName" />
          <OutputClaim ClaimTypeReferenceId="surName" />
          <OutputClaim ClaimTypeReferenceId="displayName" />
          <OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" />
          <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" />
        </OutputClaims>
        <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
      </TechnicalProfile>
      

パスワード リセットのカスタム ポリシーの構成

パスワードのリセット中に、ユーザー プロファイルの場所を特定し、ユーザー プロファイルが保存されている Azure AD B2C テナントに対してパスワードを更新する必要があります。

Azure AD B2C スターター パックの LocalAccountSignUpWithLogonEmail 技術プロファイルを変更して、ユーザーのユーザーとリージョンの検索を実行し、個別のテナントのパスワードを更新します。 次のように ValidationTechnicalProfiles を更新します。

<TechnicalProfile Id="LocalAccountDiscoveryUsingEmailAddress">
  <OutputClaims>
  ...
  <OutputClaim ClaimTypeReferenceId="ext_Api_bearerToken" DefaultValue="EMEA"/>
  </OutputClaims>
  <ValidationTechnicalProfiles>
    <ValidationTechnicalProfile ReferenceId="REST-getTokenforExternalApiCalls">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
          <Value>user_region</Value>
          <Value>EMEA</Value>
          <Action>SkipThisValidationTechnicalProfile</Action>
        </Precondition>
      </Preconditions>
    </ValidationTechnicalProfile>
    <ValidationTechnicalProfile ReferenceId="REST-regionLookup" />
    <ValidationTechnicalProfile ReferenceId="AAD-UserReadUsingEmailAddress" />
  </ValidationTechnicalProfiles>
</TechnicalProfile>

ユーザーが検証済みの電子メールを送信してパスワードを更新すると、ValidationTechnicalProfiles によって次のロジックが実行されます。

  1. 保護された API エンドポイントを呼び出すトークンを取得する

  2. セキュリティで保護された外部 REST API エンドポイントを使用してユーザーとリージョンのマッピングを検索する

    • この API 呼び出しは、すべてのパスワード リセット試行の前に行われます。アップタイム要件を維持するために、この API に適切な負荷分散、回復性、フェールオーバー メカニズムがあることを確認しておくことが重要です。

技術プロファイル LocalAccountWritePasswordUsingObjectId を変更して、新しいパスワードをローカル テナントに書き込むか、条件付きでリージョン間テナントに書き込みます。

<TechnicalProfile Id="LocalAccountWritePasswordUsingObjectId">
  ...
  <ValidationTechnicalProfiles>
    <ValidationTechnicalProfile ReferenceId="AAD-UserWritePasswordUsingObjectId">
        <Preconditions>
          <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
            <Value>user_region</Value>
            <Value>EMEA</Value>
            <Action>SkipThisValidationTechnicalProfile</Action>
          </Precondition>
        </Preconditions>
      </ValidationTechnicalProfile>
    <ValidationTechnicalProfile ReferenceId="REST-UserWritePasswordUsingObjectId-APAC">
        <Preconditions>
          <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
            <Value>user_region</Value>
            <Value>APAC</Value>
            <Action>SkipThisValidationTechnicalProfile</Action>
          </Precondition>
        </Preconditions>
      </ValidationTechnicalProfile>
  </ValidationTechnicalProfiles>
</TechnicalProfile>

ユーザーが新しいパスワードを送信すると、ValidationTechnicalProfiles によって次のロジックが実行されます。

  1. ユーザーが EMEA テナント (このテナント) に存在する場合は、ディレクトリにユーザーの新しいパスワードを書き込みます。

  2. 条件付きで、REST API 呼び出しを使用して、ユーザー プロファイルが保存されているリージョンのユーザー プロファイルに新しいパスワードを書き込みます。

    <TechnicalProfile Id="REST-UserWritePasswordUsingObjectId-APAC">
      <DisplayName>Write password to APAC tenant</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">https://myApi.com/writePasswordCrossTenant</Item>
        <Item Key="AuthenticationType">Bearer</Item>
        <Item Key="UseClaimAsBearerToken">ext_Api_bearerToken</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="DebugMode">true</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="ext_Api_bearerToken" />
        <InputClaim ClaimTypeReferenceId="objectId" />
        <InputClaim ClaimTypeReferenceId="newPassword" />
      </InputClaims>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
    

次の手順