なりすましを抑制して信頼性の高いユーザー エクスペリエンスを提供するために Azure Active Directory B2C と Deduce を構成する

このサンプル記事では、Azure Active Directory B2C (Azure AD B2C) 認証を Deduce と統合する方法についてのガイダンスを提供します。 Deduce は、インターネットで急増しているアカウント乗っ取りや不正登録の防止に力を入れています。 Deduce Identity Network は 15 万以上の Web サイトやアプリと提携しており、それらが Deduce と共有するログイン、登録、チェックアウトの数は 1 日に 14 億回を超えます。

その結果得られる ID インテリジェンスにより、財務上の問題や企業の責任に発展する攻撃を未然に防止できます。 過去の行動の分析が信頼の予測因子として使用されるため、組織は長く取引のある顧客にスムーズなユーザー エクスペリエンスを提供できます。 広範囲にわたるリスクと信頼のシグナルから、Azure AD B2C インスタンスでは十分な情報に基づいて認証を決定できます。 この統合により、組織はサインアップやサインインのプロセスで Azure AD B2C の機能を拡張して、Deduce Insights API からユーザーに関する付加的な分析情報を得ることができます。 Deduce API によって取り込まれる属性には次のものがあります。

  • Email
  • IP アドレス
  • User agent

前提条件

作業を開始するには、以下が必要です。

シナリオの説明

この統合には次のコンポーネントが含まれています。

  • Azure AD B2C – ユーザーの資格情報の検証を担当する承認サーバー。ID プロバイダーとも呼ばれます。
  • Deduce – Deduce サービスは、ユーザーから提供された入力を受け取って、ユーザーの ID に関するデジタル アクティビティ分析情報を提供します。
  • カスタム REST API – この API によって、Azure AD B2C と Deduce Insights API の統合が実装されます。

次のアーキテクチャ ダイアグラムは、この実装を示しています。image shows the architecture diagram.

手順 説明
1. ユーザーが Azure AD B2C のサインイン ページを開き、ユーザー名を入力してサインインまたはサインアップします。
2. Azure AD B2C で中間層 API が呼び出され、ユーザー属性が渡されます。
3. 中間層 API でユーザー属性が収集され、Deduce API が使用できる形式に変換されたうえで Deduceに送信されます。
4. Deduce でこの情報が使用され、リスク分析に基づいてユーザー ID を検証するために処理されます。 次に、結果が中間層 API に返されます。
5. 中間層 API でこの情報が処理され、リスク、信頼、情報の各シグナルが適切な JSON 形式で Azure AD B2C に返送されます。
6. Azure AD B2C が、中間層 API から情報を受信します。
それが失敗応答である場合は、ユーザーにエラー メッセージが表示されます。
成功応答が表示された場合、ユーザーは認証され、ディレクトリに書き込まれます。

Deduce を使用してオンボードする

Deduce アカウントを作成するには、Deduce のサポートにお問い合わせください。 アカウントが作成されると、サイト ID と、API 構成に必要な API キーを受け取ります。

以下のセクションでは統合プロセスについて説明します。

手順 1: Azure AD B2C ポリシーを構成する

スターター パックを取得する」の手順に従って、Azure AD B2C テナントを設定し、ポリシーを構成します。 このサンプル記事は Local Accounts スターター パックに基づいています。

手順 2: Azure AD B2C ユーザー インターフェイスをカスタマイズする

クライアント側から user_agent を収集するために、任意の ID で独自の **ContentDefinition** を作成して、関連する JavaScript を挿入します。 エンド ユーザー ブラウザーの user_agent 文字列を特定し、Azure AD B2C にクレームとして格納します。

  1. api.selfasserted、selfAsserted.cshtml をローカルにダウンロードします。

  2. selfAsserted.cshtml を編集して、</head> を閉じて panel-default を非表示にする追加の Style 要素を定義する前に、次の JavaScript を挿入します。

    <style>
     .panel-default   {
     margin: 0 auto;
     width: 60%;
     height: 0px;
     background-color: #296ec6;
     opacity: 1;
     border-radius: .5rem;
     border: none;
     color: #fff;
     font-size: 1em;
     box-shadow: 0 0 30px 0 #dae1f7;
     visibility: hidden;
    } 
    
    </style>
    
  3. </body> を閉じる前に、次の JavaScript コードを追加します。 このコードによってユーザーのブラウザーから user_agent が読み取られ、さらに ContentDefinition がセルフアサート技術プロファイルと共に使用されて、user_agent が出力クレームとして次のオーケストレーション ステップに返されます。

    <script>
         $("#user_agent").hide().val(window.navigator.userAgent);
         var img = new Image();
         img.onload = function() {
         document.getElementById("continue").click();
      };
         img.src = "https://login.microsoftonline.com/static/tenant/templates/images/logo.svg";
    </script>
    

手順 3: ストレージの場所を構成する

  1. ストレージ アカウントで BLOB ストレージ コンテナーを設定し、先ほど編集した **selfAsserted.cshtml** ファイルを BLOB コンテナーにアップロードします。

  2. これらの手順に従って、作成したストレージ コンテナーへの CORS アクセスを許可します。

    1. [Settings](設定)>[Allowed Origin](許可されたオリジン) に移動し、「https://your_tenant_name.b2clogin.com」を入力します。 fabrikam などの Azure AD B2C テナントの名前に your-tenant- name を置き換えます。 テナント名を入力するときは、すべて小文字を使用します。

    2. [許可されたメソッド] で、GET および PUT を選択します。

    3. [保存] を選択します。

手順 4: コンテンツ定義を構成する

ユーザー インターフェイスをカスタマイズするには、ContentDefinition 要素でカスタマイズされた HTMLコンテンツを含む URL を指定します。 セルフアサート技術プロファイルまたはオーケストレーション ステップで、この ContentDefinition 識別子をポイントします。

  1. TrustFrameworksExtension.xml を開き、新しい ContentDefinition を定義してセルフアサート技術プロファイルをカスタマイズします。

  2. BuildingBlocks 要素を見つけ、**api.selfassertedDeduce** ContentDefinition を追加します。

     <BuildingBlocks>
     ...
     <ContentDefinitions>
       <ContentDefinition Id="api.selfassertedDeduce">
         <LoadUri>https://<STORAGE-ACCOUNT-NAME>.blob.core.windows.net/<CONTAINER>/selfAsserted.cshtml</LoadUri>
         <RecoveryUri>~/common/default_page_error.html</RecoveryUri>
         <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.7</DataUri>
         <Metadata>
           <Item Key="DisplayName">Signin and Signup Deduce</Item>
         </Metadata>
       </ContentDefinition>
     </ContentDefinitions>
       ...
    </BuildingBlocks>
    

LoadUri を、手順 1 で作成した selfAsserted.cshtml ファイルを指す URL に置き換えます。

手順 5: Deduce の ClaimType を追加する

ClaimsSchema要素は、ポリシーの一部として参照可能な要求の種類を定義します。 Deduce でサポートされるクレームを追加することができます。

  1. TrustFrameworksExtension.xml を開きます

  2. **BuildingBlocks** 要素で、Deduce がサポートする ID クレームを追加できます。

      <BuildingBlocks>
    ...
     <ClaimsSchema>
      <!-- Claims for Deduce API request body -->
       <ClaimType Id="site">
         <DisplayName>Site ID</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>Deduce Insight API site id</AdminHelpText>
       </ClaimType>
    
       <ClaimType Id="ip">
         <DisplayName>IP Address</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
    
       <ClaimType Id="apikey">
         <DisplayName>API Key</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
    
       <ClaimType Id="action">
         <DisplayName>Contextual action</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
    
       <!-- End of Claims for Deduce API request body -->
    
       <!-- Rest API call request body to deduce insight API -->
       <ClaimType Id="deduce_requestbody">
         <DisplayName>Request body for insight api</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>Request body for insight api</AdminHelpText>
       </ClaimType>
    
       <ClaimType Id="deduce_trust_response">
         <DisplayName>Response body for insight api</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>Response body for insight api</AdminHelpText>
       </ClaimType>
       <!-- End of Rest API call request body to deduce insight API -->
    
       <!-- Response claims from Deduce Insight  API -->
    
       <ClaimType Id="data.signals.trust">
         <DisplayName>Trust collection</DisplayName>
         <DataType>stringCollection</DataType>
         <AdminHelpText>List of asserted trust</AdminHelpText>
       </ClaimType>
    
       <ClaimType Id="data.signals.info">
         <DisplayName>Trust collection</DisplayName>
         <DataType>stringCollection</DataType>
         <AdminHelpText>List of asserted info</AdminHelpText>
       </ClaimType>
    
       <ClaimType Id="data.signals.risk">
         <DisplayName>Trust collection</DisplayName>
         <DataType>stringCollection</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
    
       <ClaimType Id="data.network.company_name">
         <DisplayName>data.network.company_name</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.crawler_name">
         <DisplayName>data.network.crawler_name</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.is_corporate">
         <DisplayName>data.network.is_corporate</DisplayName>
         <DataType>boolean</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.is_education">
         <DisplayName>data.network.is_education</DisplayName>
         <DataType>boolean</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.is_hosting">
         <DisplayName>data.network.is_hosting</DisplayName>
         <DataType>boolean</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.is_mobile">
         <DisplayName>data.network.is_mobile</DisplayName>
         <DataType>boolean</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.is_proxy">
         <DisplayName>data.network.is_proxy"</DisplayName>
         <DataType>boolean</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.is_tor">
         <DisplayName>data.network.is_tor</DisplayName>
         <DataType>boolean</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.is_vpn_capable">
         <DisplayName>data.network.is_vpn_capable</DisplayName>
         <DataType>boolean</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.is_vpn_confirmed">
         <DisplayName>data.network.is_vpn_confirmed</DisplayName>
         <DataType>boolean</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.is_vpn_suspect">
         <DisplayName>data.network.is_vpn_suspect</DisplayName>
         <DataType>boolean</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.isp_name">
         <DisplayName>data.network.isp_name</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.network.vpn_name">
         <DisplayName>data.network.vpn_name</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.geo.city">
         <DisplayName>data.geo.city</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.geo.country">
         <DisplayName>data.geo.country</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.geo.lat">
         <DisplayName>data.geo.lat</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.geo.long">
         <DisplayName>data.geo.long</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.geo.state">
         <DisplayName>data.geo.state</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.device.ua_brand">
         <DisplayName>data.device.ua_brand</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.device.ua_browser">
         <DisplayName>data.device.ua_browser</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.device.ua_device_type">
         <DisplayName>data.device.ua_device_type</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.device.ua_name">
         <DisplayName>data.device.ua_name</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.device.ua_os">
         <DisplayName>data.device.ua_os</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.device.ua_type">
         <DisplayName>data.device.ua_type</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.device.ua_version">
         <DisplayName>data.device.ua_version</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>List of asserted risk</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.activity.email.ip_count">
         <DisplayName>data.activity.email.ip_count</DisplayName>
         <DataType>int</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.activity.email.lastseen">
         <DisplayName>data.activity.email.lastseen</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.activity.email.frequency">
         <DisplayName>data.activity.email.frequency</DisplayName>
         <DataType>int</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.activity.emailip.frequency">
         <DisplayName>data.activity.emailip.frequency</DisplayName>
         <DataType>int</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.activity.emailip.lastseen">
         <DisplayName>data.activity.emailip.lastseen</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.activity.emailip.match">
         <DisplayName>data.activity.emailip.match</DisplayName>
         <DataType>boolean</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.activity.emailip.rank_email">
         <DisplayName>data.activity.emailip.rank_email</DisplayName>
         <DataType>int</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.activity.emailip.rank_ip">
         <DisplayName>data.activity.emailip.rank_ip</DisplayName>
         <DataType>int</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.activity.ip.email_count">
         <DisplayName>data.activity.ip.email_count</DisplayName>
         <DataType>int</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
       <ClaimType Id="data.activity.ip.lastseen">
         <DisplayName>data.activity.ip.lastseen</DisplayName>
         <DataType>string</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
    
       <ClaimType Id="data.activity.ip.frequency">
         <DisplayName>data.activity.ip.frequency</DisplayName>
         <DataType>int</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
    
       <ClaimType Id="data.sent_timestamp">
         <DisplayName>datasent_timestamp</DisplayName>
         <DataType>long</DataType>
         <AdminHelpText>Add help text here</AdminHelpText>
       </ClaimType>
    
       <ClaimType Id="user_agent">
         <DisplayName>User Agent</DisplayName>
         <DataType>string</DataType>
         <UserHelpText>Add help text here</UserHelpText>
         <UserInputType>TextBox</UserInputType>
       </ClaimType>
    
       <ClaimType Id="correlationId">
         <DisplayName>correlation ID</DisplayName>
         <DataType>string</DataType>
       </ClaimType>
     <!-- End Response claims from Deduce Insight API -->
     ...
     </ClaimsSchema>
     ...
     </BuildingBlocks>
    
    

手順 6: Deduce ClaimsProvider を追加する

クレーム プロバイダーは、その技術プロファイルを通じてさまざまな種類の利用者と通信するインターフェイスです。

  • SelfAsserted-UserAgent セルフアサート技術プロファイルは、クライアント側から user_agent を収集するために使用されます。

  • deduce_insight_api 技術プロファイルは、入力クレーム コレクションでデータを Deduce RESTful サービスに送信し、出力クレーム コレクションで返却データを受信します。 詳細については、Azure AD B2C カスタム ポリシーでの REST API クレーム交換の統合に関する記事を参照してください。

Deduce をクレーム プロバイダーとして定義するには、ポリシーの拡張ファイルで ClaimsProvider 要素に Deduce を追加します。

  1. TrustFrameworkExtensions.xml を開きます。

  2. ClaimsProvider 要素を見つけます。 存在しない場合は、次のように新しい ClaimsProvider を追加します。

     <ClaimsProvider>
       <DisplayName>Deduce REST API</DisplayName>
       <TechnicalProfiles>
         <TechnicalProfile Id="SelfAsserted-UserAgent">
           <DisplayName>Pre-login</DisplayName>
           <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral,         PublicKeyToken=null" />
           <Metadata>
             <Item Key="ContentDefinitionReferenceId">api.selfassertedDeduce</Item>
             <Item Key="setting.showCancelButton">false</Item>
             <Item Key="language.button_continue">Continue</Item>
           </Metadata>
           <OutputClaims>
             <OutputClaim ClaimTypeReferenceId="user_agent" />
           </OutputClaims>
         </TechnicalProfile>
         <TechnicalProfile Id="deduce_insight_api">
           <DisplayName>Get customer insight data from deduce api</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://deduceproxyapi.azurewebsites.net/api/Deduce/DeduceInsights</Item>
             <Item Key="AuthenticationType">None</Item>
             <Item Key="SendClaimsIn">Body</Item>
             <Item Key="ResolveJsonPathsInJsonTokens">true</Item>
             <Item Key="AllowInsecureAuthInProduction">true</Item>
             <Item Key="DebugMode">true</Item>
             <Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
           </Metadata>
           <InputClaims>
             <InputClaim ClaimTypeReferenceId="user_agent" />
             <InputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
             <InputClaim ClaimTypeReferenceId="ip" DefaultValue="{Context:IPAddress}" AlwaysUseDefaultValue="true" />
             <InputClaim ClaimTypeReferenceId="apikey" DefaultValue="<DEDUCE API KEY>" />
             <InputClaim ClaimTypeReferenceId="action" DefaultValue="auth.success.password" />
             <InputClaim ClaimTypeReferenceId="site" DefaultValue="<SITE>" />
           </InputClaims>
           <OutputClaims>
             <OutputClaim ClaimTypeReferenceId="data.sent_timestamp" PartnerClaimType="data.sent_timestamp" />
             <OutputClaim ClaimTypeReferenceId="data.activity.ip.frequency" PartnerClaimType="data.activity.ip.frequency" />
             <OutputClaim ClaimTypeReferenceId="data.activity.ip.lastseen" PartnerClaimType="data.activity.ip.lastseen" />
             <OutputClaim ClaimTypeReferenceId="data.activity.ip.email_count" PartnerClaimType="data.activity.ip.email_count" />
             <OutputClaim ClaimTypeReferenceId="data.activity.email.ip_count" PartnerClaimType="data.activity.email.ip_count" />
             <OutputClaim ClaimTypeReferenceId="data.activity.email.lastseen" PartnerClaimType="data.activity.email.lastseen" />
             <OutputClaim ClaimTypeReferenceId="data.activity.email.frequency" PartnerClaimType="data.activity.email.frequency" />
             <OutputClaim ClaimTypeReferenceId="data.activity.emailip.frequency" PartnerClaimType="data.activity.emailip.frequency" />
             <OutputClaim ClaimTypeReferenceId="data.activity.emailip.lastseen" PartnerClaimType="data.activity.emailip.lastseen" />
             <OutputClaim ClaimTypeReferenceId="data.activity.emailip.match" PartnerClaimType="data.activity.emailip.match" />
             <OutputClaim ClaimTypeReferenceId="data.activity.emailip.rank_email" PartnerClaimType="data.activity.emailip.rank_email" />
             <OutputClaim ClaimTypeReferenceId="data.activity.emailip.rank_ip" PartnerClaimType="data.activity.emailip.rank_ip" />
             <OutputClaim ClaimTypeReferenceId="data.signals.trust" PartnerClaimType="data.signals.trust" />
             <OutputClaim ClaimTypeReferenceId="data.signals.info" PartnerClaimType="data.signals.info" />
             <OutputClaim ClaimTypeReferenceId="data.signals.risk" PartnerClaimType="data.signals.risk" />
             <OutputClaim ClaimTypeReferenceId="data.network.company_name" PartnerClaimType="data.network.company_name" />
             <OutputClaim ClaimTypeReferenceId="data.network.crawler_name" PartnerClaimType="data.network.crawler_name" />
             <OutputClaim ClaimTypeReferenceId="data.network.is_corporate" PartnerClaimType="data.network.is_corporate" />
             <OutputClaim ClaimTypeReferenceId="data.network.is_education" PartnerClaimType="data.network.is_education" />
             <OutputClaim ClaimTypeReferenceId="data.network.is_hosting" PartnerClaimType="data.network.is_hosting" />
             <OutputClaim ClaimTypeReferenceId="data.network.is_mobile" PartnerClaimType="data.network.is_mobile" />
             <OutputClaim ClaimTypeReferenceId="data.network.is_proxy" PartnerClaimType="data.network.is_proxy" />
             <OutputClaim ClaimTypeReferenceId="data.network.is_tor" PartnerClaimType="data.network.is_tor" />
             <OutputClaim ClaimTypeReferenceId="data.network.is_vpn_capable" PartnerClaimType="data.network.is_vpn_capable" />
             <OutputClaim ClaimTypeReferenceId="data.network.is_vpn_confirmed" PartnerClaimType="data.network.is_vpn_confirmed" />
             <OutputClaim ClaimTypeReferenceId="data.network.is_vpn_suspect" PartnerClaimType="data.network.is_vpn_suspect" />
             <OutputClaim ClaimTypeReferenceId="data.network.isp_name" PartnerClaimType="data.network.isp_name" />
             <OutputClaim ClaimTypeReferenceId="data.network.vpn_name" PartnerClaimType="data.network.vpn_name" />
             <OutputClaim ClaimTypeReferenceId="data.geo.city" PartnerClaimType="data.geo.city" />
             <OutputClaim ClaimTypeReferenceId="data.geo.country" PartnerClaimType="data.geo.country" />
             <OutputClaim ClaimTypeReferenceId="data.geo.lat" PartnerClaimType="data.geo.lat" />
             <OutputClaim ClaimTypeReferenceId="data.geo.long" PartnerClaimType="data.geo.long" />
             <OutputClaim ClaimTypeReferenceId="data.geo.state" PartnerClaimType="data.geo.state" />
             <OutputClaim ClaimTypeReferenceId="data.device.ua_brand" PartnerClaimType="data.device.ua_brand" />
             <OutputClaim ClaimTypeReferenceId="data.device.ua_browser" PartnerClaimType="data.device.ua_browser" />
             <OutputClaim ClaimTypeReferenceId="data.device.ua_device_type" PartnerClaimType="data.device.ua_device_type" />
             <OutputClaim ClaimTypeReferenceId="data.device.ua_name" PartnerClaimType="data.device.ua_name" />
             <OutputClaim ClaimTypeReferenceId="data.device.ua_os" PartnerClaimType="data.device.ua_os" />
             <OutputClaim ClaimTypeReferenceId="data.device.ua_type" PartnerClaimType="data.device.ua_type" />
             <OutputClaim ClaimTypeReferenceId="data.device.ua_version" PartnerClaimType="data.device.ua_version" />
           </OutputClaims>
         </TechnicalProfile>
       </TechnicalProfiles>
     </ClaimsProvider>
    
    

apikeysite を、初回オンボード時に Deduce から提供された情報に置き換えます。

手順 7: ユーザー体験を追加する

この時点で、Deduce RESTfull API は設定されていますが、サインアップまたはサインインのページではまだ使用できません。 独自のカスタム ユーザー体験がない場合は、既存のテンプレート ユーザー体験の複製を作成してください。そうでない場合は、次の手順に進みます。

  1. スターター パックから TrustFrameworkBase.xml ファイルを開きます。

  2. ID=Id=SignUpOrSignIn を含む UserJourneys 要素を見つけ、その内容全体をコピーします。

  3. TrustFrameworkExtensions.xml を開き、UserJourneys 要素を見つけます。 要素が存在しない場合は追加します。

  4. コピーした UserJourney 要素の内容全体を UserJourneys 要素の子として貼り付けます。

  5. ユーザー体験の Id の名前を変更します。 たとえば、Id=CustomSignUpSignIn のように指定します。

手順 8: Deduce API をユーザー体験に追加する

ユーザー体験を用意できたので、Deduce を呼び出すオーケストレーション ステップを追加します。

  1. ユーザー体験内で、Type=CombinedSignInAndSignUp または Type=ClaimsProviderSelection を含むオーケストレーション ステップ要素を見つけます。 これは通常、最初のオーケストレーション ステップです。

  2. SelfAsserted-UserAgent 技術プロファイルを呼び出す新しいオーケストレーション ステップを追加します。

  3. **deduce_insight_api** 技術プロファイルを呼び出す新しいオーケストレーション ステップを追加します。

    次に示す UserJourney の例は、Local Accounts スターター パックに基づいています。

     <UserJourneys>
      <UserJourney Id="CustomSignUpOrSignIn">
       <OrchestrationSteps>
         <OrchestrationStep Order="1" Type="ClaimsExchange">
           <ClaimsExchanges>
             <ClaimsExchange Id="Browser-UserAgent" TechnicalProfileReferenceId="SelfAsserted-UserAgent" />
           </ClaimsExchanges>
         </OrchestrationStep>
         <OrchestrationStep Order="2" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
           <ClaimsProviderSelections>
             <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
           </ClaimsProviderSelections>
           <ClaimsExchanges>
             <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
           </ClaimsExchanges>
         </OrchestrationStep>
    
         <OrchestrationStep Order="3" Type="ClaimsExchange">
           <Preconditions>
             <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
               <Value>objectId</Value>
               <Action>SkipThisOrchestrationStep</Action>
             </Precondition>
           </Preconditions>
           <ClaimsExchanges>
             <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
           </ClaimsExchanges>
         </OrchestrationStep>
    
         <!-- This step reads any user attributes that we may not have received when in the token. -->
         <OrchestrationStep Order="4" Type="ClaimsExchange">
           <ClaimsExchanges>
             <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
           </ClaimsExchanges>
         </OrchestrationStep>
         <OrchestrationStep Order="5" Type="ClaimsExchange">
           <ClaimsExchanges>
             <ClaimsExchange Id="DecideInsights" TechnicalProfileReferenceId="deduce_insight_api" />
           </ClaimsExchanges>
         </OrchestrationStep>
         <OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
    
       </OrchestrationSteps>
       <ClientDefinition ReferenceId="DefaultWeb" />
     </UserJourney>
    </UserJourneys>
    

手順 9: 証明書利用者ポリシーを構成する

証明書利用者ポリシーは、Azure AD B2C が実行されるユーザー体験を指定します。 SignUpOrSignIn_WithDeduce TechnicalProfile 要素の OutputClaims 要素を調整して、アプリケーションに渡すクレームを制御することもできます。 このサンプルでは、アプリケーションが中間層 API から返される情報を受信します。

    <RelyingParty>
        <DefaultUserJourney ReferenceId="CustomSignUpOrSignIn" />
        <UserJourneyBehaviors>
            <ScriptExecution>Allow</ScriptExecution>
        </UserJourneyBehaviors>
        <TechnicalProfile Id="PolicyProfile">
            <DisplayName>PolicyProfile</DisplayName>
            <Protocol Name="OpenIdConnect" />
            <OutputClaims>
                <!-- <OutputClaim ClaimTypeReferenceId="user_agent"   /> -->
                <OutputClaim ClaimTypeReferenceId="displayName" />
                <OutputClaim ClaimTypeReferenceId="givenName" />
                <OutputClaim ClaimTypeReferenceId="surname" />
                <OutputClaim ClaimTypeReferenceId="email" />
                <OutputClaim ClaimTypeReferenceId="correlationId" DefaultValue="{Context:CorrelationId}" />
                <OutputClaim ClaimTypeReferenceId="data.sent_timestamp" PartnerClaimType="data.sent_timestamp" />
                <OutputClaim ClaimTypeReferenceId="data.activity.ip.frequency" PartnerClaimType="data.activity.ip.frequency" />
                <OutputClaim ClaimTypeReferenceId="data.activity.ip.lastseen" PartnerClaimType="data.activity.ip.lastseen" />
                <OutputClaim ClaimTypeReferenceId="data.activity.ip.email_count" PartnerClaimType="data.activity.ip.email_count" />
                <OutputClaim ClaimTypeReferenceId="data.activity.email.ip_count" PartnerClaimType="data.activity.email.ip_count" />
                <OutputClaim ClaimTypeReferenceId="data.activity.email.lastseen" PartnerClaimType="data.activity.email.lastseen" />
                <OutputClaim ClaimTypeReferenceId="data.activity.email.frequency" PartnerClaimType="data.activity.email.frequency" />
                <OutputClaim ClaimTypeReferenceId="data.activity.emailip.frequency" PartnerClaimType="data.activity.emailip.frequency" />
                <OutputClaim ClaimTypeReferenceId="data.activity.emailip.lastseen" PartnerClaimType="data.activity.emailip.lastseen" />
                <OutputClaim ClaimTypeReferenceId="data.activity.emailip.match" PartnerClaimType="data.activity.emailip.match" />
                <OutputClaim ClaimTypeReferenceId="data.activity.emailip.rank_email" PartnerClaimType="data.activity.emailip.rank_email" />
                <OutputClaim ClaimTypeReferenceId="data.activity.emailip.rank_ip" PartnerClaimType="data.activity.emailip.rank_ip" />
                <OutputClaim ClaimTypeReferenceId="data.signals.trust" PartnerClaimType="data.signals.trust" />
                <OutputClaim ClaimTypeReferenceId="data.signals.info" PartnerClaimType="data.signals.info" />
                <OutputClaim ClaimTypeReferenceId="data.signals.risk" PartnerClaimType="data.signals.risk" />
                <OutputClaim ClaimTypeReferenceId="data.network.company_name" PartnerClaimType="data.network.company_name" />
                <OutputClaim ClaimTypeReferenceId="data.network.crawler_name" PartnerClaimType="data.network.crawler_name" />
                <OutputClaim ClaimTypeReferenceId="data.network.is_corporate" PartnerClaimType="data.network.is_corporate" />
                <OutputClaim ClaimTypeReferenceId="data.network.is_education" PartnerClaimType="data.network.is_education" />
                <OutputClaim ClaimTypeReferenceId="data.network.is_hosting" PartnerClaimType="data.network.is_hosting" />
                <OutputClaim ClaimTypeReferenceId="data.network.is_mobile" PartnerClaimType="data.network.is_mobile" />
                <OutputClaim ClaimTypeReferenceId="data.network.is_proxy" PartnerClaimType="data.network.is_proxy" />
                <OutputClaim ClaimTypeReferenceId="data.network.is_tor" PartnerClaimType="data.network.is_tor" />
                <OutputClaim ClaimTypeReferenceId="data.network.is_vpn_capable" PartnerClaimType="data.network.is_vpn_capable" />
                <OutputClaim ClaimTypeReferenceId="data.network.is_vpn_confirmed" PartnerClaimType="data.network.is_vpn_confirmed" />
                <OutputClaim ClaimTypeReferenceId="data.network.is_vpn_suspect" PartnerClaimType="data.network.is_vpn_suspect" />
                <OutputClaim ClaimTypeReferenceId="data.network.isp_name" PartnerClaimType="data.network.isp_name" />
                <OutputClaim ClaimTypeReferenceId="data.network.vpn_name" PartnerClaimType="data.network.vpn_name" />
                <OutputClaim ClaimTypeReferenceId="data.geo.city" PartnerClaimType="data.geo.city" />
                <OutputClaim ClaimTypeReferenceId="data.geo.country" PartnerClaimType="data.geo.country" />
                <OutputClaim ClaimTypeReferenceId="data.geo.lat" PartnerClaimType="data.geo.lat" />
                <OutputClaim ClaimTypeReferenceId="data.geo.long" PartnerClaimType="data.geo.long" />
                <OutputClaim ClaimTypeReferenceId="data.geo.state" PartnerClaimType="data.geo.state" />
                <OutputClaim ClaimTypeReferenceId="data.device.ua_brand" PartnerClaimType="data.device.ua_brand" />
                <OutputClaim ClaimTypeReferenceId="data.device.ua_browser" PartnerClaimType="data.device.ua_browser" />
                <OutputClaim ClaimTypeReferenceId="data.device.ua_device_type" PartnerClaimType="data.device.ua_device_type" />
                <OutputClaim ClaimTypeReferenceId="data.device.ua_name" PartnerClaimType="data.device.ua_name" />
                <OutputClaim ClaimTypeReferenceId="data.device.ua_os" PartnerClaimType="data.device.ua_os" />
                <OutputClaim ClaimTypeReferenceId="data.device.ua_type" PartnerClaimType="data.device.ua_type" />
                <OutputClaim ClaimTypeReferenceId="data.device.ua_version" PartnerClaimType="data.device.ua_version" />
                <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
            </OutputClaims>
            <SubjectNamingInfo ClaimType="sub" />
        </TechnicalProfile>
    </RelyingParty>

手順 10: カスタム ポリシーをアップロードする

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

  2. 複数のテナントにアクセスできる場合、上部のメニューの [設定] アイコンを選択し、[ディレクトリとサブスクリプション] メニューからお使いの Azure AD B2C テナントに切り替えます。

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

  4. [ポリシー] で [Identity Experience Framework] を選択します。

  5. [カスタム ポリシーのアップロード] を選択し、変更した 2 つのポリシー ファイルを拡張ポリシー (TrustFrameworkBase.xml など)、証明書利用者ポリシー (B2C_1A_signupなど) の順序でアップロードします。

手順 11: カスタム ポリシーをテストする

  1. 証明書利用者ポリシー (B2C_1A_signup など) を選択します。

  2. [アプリケーション] には、前に登録した Web アプリケーションを選択します。 [応答 URL]https://jwt.ms と表示されます。

  3. [今すぐ実行] ボタンを選択します。

  4. サインアップ ポリシーによって、すぐに Deduce が呼び出されます。 サインインが使用された場合は、Deduce を選択して Deduce でサインインします。

サインイン プロセスが成功すると、ブラウザーは https://jwt.ms にリダイレクトされ、Azure AD B2C によって返されたトークンの内容が表示されます。

次のステップ

追加情報については、次の記事を参照してください。