你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

为 Azure Active Directory B2C 配置 Deduce 以打击身份欺诈并创建受信任的用户体验

在本示例文章中,我们提供了有关如何将 Azure Active Directory B2C (Azure AD B2C) 身份验证与 Deduce 集成的指导。 Deuce 专注于阻止帐户接管和注册欺诈 — Internet 上增长最快的欺诈行为。 由 150,000 个以上的网站和应用组成的联盟为 Deduce Identity Network 提供支持,这些网站和应用每天与 Deduce 共享登录、注册和签出信息的次数超过 14 亿次。

由此产生的身份情报可以阻止攻击,使其无法造成财务问题和公司责任。 它使用历史行为分析作为信任预测器,以便组织可以为其最佳客户提供顺畅的用户体验。 一系列全面的风险和信任信号可以为每个使用 Azure AD B2C 实例的身份验证决策提供信息。 通过此集成,组织可以在注册或登录过程中扩展其 Azure AD B2C 功能,以便从 Deduce 见解 API 获取有关用户的其他见解。 Deduce API 引入的一些属性包括:

  • 电子邮件
  • IP 地址
  • 用户代理

先决条件

若要开始,需要:

方案描述

该集成包括以下组件:

  • Azure AD B2C – 授权服务器,负责验证用户的凭据,也称为标识提供者。
  • Deduce – Deduce 服务接受用户提供的输入,并提供有关用户标识的数字活动见解。
  • 自定义 REST API – 此 API 实现 Azure AD B2C 与 Deduce 见解 API 之间的集成。

以下体系结构图显示了实现方式:image shows the architecture diagram.

步骤 说明
1. 用户打开 Azure AD B2C 的登录页,然后通过输入用户名登录或注册。
2. Azure AD B2C 调用中间层 API 并传递用户属性。
3. 中间层 API 收集用户属性并将其转换为 Deduce API 可以使用的格式,然后将其发送到 Deduce。
4. Deduce 会使用该信息并加以处理,以根据风险分析来验证用户标识。 然后,它会将结果返回给中间层 API。
5. 中间层 API 处理该信息,并将风险、信任和信息信号以正确的 JSON 格式发送回 Azure AD B2C。
6. Azure AD B2C 接收从中间层 API 返回的信息。
如果它显示“失败”响应,则会向用户显示错误消息。
如果它显示“成功”响应,则表明用户已通过身份验证并会被写入到目录中。

加入到 Deduce

若要创建 Deduce 帐户,请联系 Deduce 支持人员。 创建帐户后,将收到 API 配置所需的站点 ID 和 API 密钥。

以下各部分介绍了集成过程。

步骤 1:配置 Azure AD B2C 策略

按照获取新手包中的说明了解如何设置 Azure AD B2C 租户以及如何配置策略。 此示例文章基于“本地帐户”新手包。

步骤 2:自定义 Azure AD B2C 用户界面

若要从客户端收集 user_agent,请使用任意 ID 创建自己的 **ContentDefinition** 以包含相关的 JavaScript。 确定最终用户浏览器的 user_agent 字符串,并将其作为声明存储在 Azure AD B2C 中。

  1. 在本地下载 api.selfasserted、selfAsserted.cshtml

  2. 编辑 selfAsserted.cshtml 以在 </head> 结尾之前包含以下 JavaScript,从而定义另一个 Style 元素以隐藏 panel-default。

    <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. 转到“设置”>“允许的原点”,输入 https://your_tenant_name.b2clogin.com 。 将 your-tenant- name 替换为你的 Azure AD B2C 租户名称,例如 fabrikam。 输入租户名称时全部使用小写字母。

    2. 对于“允许的方法”,请选择 GETPUT

    3. 选择“保存”。

步骤 4:配置内容定义

若要自定义用户界面,请在包含自定义 HTML 内容的 ContentDefinition 元素中指定一个 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 支持的其他标识声明。

      <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 技术配置文件通过一个输入声明集合将数据发送到 RESTful 服务,并在一个输出声明集合中接收返回的数据。 有关详细信息,请参阅在 Azure AD B2C 自定义策略中集成 REST API 声明交换

要将 Deduce 定义为声明提供程序,可将其添加到策略的扩展文件中的 ClaimsProvider 元素。

  1. 打开 TrustFrameworkExtensions.xml

  2. 找到 ClaimsProviders 元素。 如果它不存在,请添加一个新的 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=SignUpOrSignIn 的 UserJourney 元素的完整内容。

  3. 打开 TrustFrameworkExtensions.xml 并找到 UserJourney元素。 如果该元素不存在,请添加一个。

  4. 将复制的 UserJourney 元素的完整内容粘贴为 UserJourneys 元素的子级。

  5. 对用户旅程的 Id 进行重命名。 例如: Id=CustomSignUpSignIn

步骤 8:将 Deduce API 添加到用户旅程

拥有用户旅程后,添加业务流程步骤以调用 Deduce。

  1. 在用户旅程中,查找包含 Type=CombinedSignInAndSignUpType=ClaimsProviderSelection 的业务流程步骤元素。 这通常是第一个业务流程步骤。

  2. 添加新的业务流程步骤以调用 SelfAsserted-UserAgent 技术配置文件。

  3. 添加新的业务流程步骤以调用 **deduce_insight_api** 技术配置文件。

    以下 UserJourney 示例基于本地帐户新手包:

     <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 门户

  2. 如果有权访问多个租户,请选择顶部菜单中的“设置”图标,切换到“目录 + 订阅”菜单中的 Azure AD B2C 租户

  3. Azure 门户中,搜索并选择 Azure AD B2C。

  4. 在策略下,选择 Identity Experience Framework。

  5. 选择“上传自定义策略”,然后上传已更改的两个策略文件,其顺序为:先上传扩展策略(例如 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 返回的令牌内容。

后续步骤

有关更多信息,请查看以下文章: