【问题标题】:Azure B2C custom policy with Rest API not sending objectId in request带有 Rest API 的 Azure B2C 自定义策略未在请求中发送 objectId
【发布时间】:2020-10-15 17:28:28
【问题描述】:

我正在尝试设置自定义 Azure B2C 策略。该策略将请求发送到端点,但不会在正文中填充 objectId

    <ClaimsProvider>
      <DisplayName>REST API SignUp</DisplayName>
      <TechnicalProfiles>

        <!-- Custom Restful service -->
        <TechnicalProfile Id="REST-API-SignUp">
          <DisplayName>Validate user's input data and Save details to Web 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://xxxxxxxxxxx.azurewebsites.net/api/Users/RegisterNewUser</Item>
            <Item Key="AllowInsecureAuthInProduction">true</Item>
            <Item Key="AuthenticationType">None</Item>
            <Item Key="SendClaimsIn">Body</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="objectId" />
            <InputClaim ClaimTypeReferenceId="email" />
            <InputClaim ClaimTypeReferenceId="displayName"/>
            <InputClaim ClaimTypeReferenceId="surname" />
            <InputClaim ClaimTypeReferenceId="phoneNumber" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="roles" PartnerClaimType="roles" />
          </OutputClaims>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>

        <!-- Add validation technical profile to LocalAccountSignUpWithLogonEmail technical profile -->
        <TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
          <Metadata>
            <Item Key="ContentDefinitionReferenceId">api.localaccountsignup</Item>
          </Metadata>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="roles" PartnerClaimType="roles" DefaultValue="" />
          </OutputClaims>
          <ValidationTechnicalProfiles>
            <ValidationTechnicalProfile ReferenceId="REST-API-SignUp" />
          </ValidationTechnicalProfiles>
        </TechnicalProfile>

      </TechnicalProfiles>
    </ClaimsProvider>
  </ClaimsProviders>

除了 objectId 之外,所有其他 InputClaims 都填充到请求正文中

{"email":"sakkiexxx@xxxxch","displayName":"Sakkie","surname":"NA","phoneNumber":"9876543215"}

我有以下编排步骤

 <UserJourney Id="SignUp">

      <OrchestrationSteps>
        <!-- Track that we have received a sign in request -->
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="TrackSignUp-RequestReceived" TechnicalProfileReferenceId="AppInsights-SignUpRequest" />
          </ClaimsExchanges>
        </OrchestrationStep>

        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
          </ClaimsExchanges>
        </OrchestrationStep>
        ...

然后 LocalAccountSignUpWithLogonEmail 技术配置文件输出对象 ID

<ClaimsProvider>
      <DisplayName>Local Account</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
          <DisplayName>Email signup</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <Metadata>
            <Item Key="IpAddressClaimReferenceId">IpAddress</Item>
            <Item Key="ContentDefinitionReferenceId">api.localaccountsignup</Item>
            <Item Key="language.button_continue">Sign Up</Item>
          </Metadata>
          <CryptographicKeys>
            <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
          </CryptographicKeys>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="email" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" Required="true" />
            <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />
            <OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />
            <OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
            <OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" />
            <OutputClaim ClaimTypeReferenceId="newUser" />
            <!-- Optional claims, to be collected from the user -->
            <OutputClaim ClaimTypeReferenceId="displayName" />
            <!-- <OutputClaim ClaimTypeReferenceId="givenName" /> -->
            <OutputClaim ClaimTypeReferenceId="surname" />
            <OutputClaim ClaimTypeReferenceId="phoneNumber" />
          </OutputClaims>
          <ValidationTechnicalProfiles>
            <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
          </ValidationTechnicalProfiles>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
        </TechnicalProfile>
        ............

【问题讨论】:

  • 您是否在另一个技术配置文件中输出了对象 ID,该配置文件由您的用户旅程中的编排步骤显式调用?如果不是,则为空。
  • @JasSuri 我上面更新了以下编排步骤
  • 我认为这是因为您的 rest api 调用是在 userwrite 验证技术配置文件之前执行的。所以此时除了objectid之外的一切都存在。
  • 好的,所以它与时间有关。我删除了我的 api 调用作为验证配置文件,并将其作为额外的编排步骤添加到我的用户旅程中,然后填充了该字段。 @JasSuri 感谢您的帮助
  • ;) 很高兴它成功了。但理想的选择是复制 TP 并重命名它。将 write 和 rest 调用都添加为 VTP。这是为了确保如果 REST API 抛出错误,它可以在屏幕上显示给用户。

标签: azure-ad-b2c


【解决方案1】:

我更新了我的用户旅程,将 API 调用作为一个单独的步骤包含在内,这整理出了 objectId

 <UserJourney Id="SignUp">

      <OrchestrationSteps>
        <!-- Track that we have received a sign in request -->
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="TrackSignUp-RequestReceived" TechnicalProfileReferenceId="AppInsights-SignUpRequest" />
          </ClaimsExchanges>
        </OrchestrationStep>

        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
          </ClaimsExchanges>
        </OrchestrationStep>

        <OrchestrationStep Order="3" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="Web-API-Update" TechnicalProfileReferenceId="REST-API-SignUp" />
          </ClaimsExchanges>
        </OrchestrationStep>

【讨论】:

    【解决方案2】:

    为您的用户旅程添加额外的步骤是其中一种选择。 您也可以使用 ValidationProfile 作为替代方案,在这种情况下,您将更改以下 XML

    <ValidationTechnicalProfiles>
        <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
    </ValidationTechnicalProfiles>
    

    到这里

    <ValidationTechnicalProfiles>
        <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
        <ValidationTechnicalProfile ReferenceId="REST-API-SignUp" />
    </ValidationTechnicalProfiles>
    

    有一个“但是”,即两种解决方案都有缺点。 ObjectId 在技术配置文件AAD-UserWriteUsingLogonEmail 中生成。这意味着您的帐户是在 Azure AD 中创建的。如果您的下一步或验证配置文件未能调用 API,您最终可能会处于注册帐户但对象 ID 未存储在 API 中的状态。这也是反过来的,如果您的 API 向用户提供额外的声明,这些声明不会保存在用户的个人资料中。

    有关技术简介AAD-UserWriteUsingLogonEmail 的更多信息可以在官方文档中找到:
    https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-technical-profile#azure-ad-technical-provider-operations

    验证技术配置文件相同:
    https://docs.microsoft.com/en-us/azure/active-directory-b2c/validation-technical-profile

    【讨论】:

      【解决方案3】:

      这正是发生在我身上的事。我尝试添加 AAD-UserWriteUsingLogonEmail 作为 TrustFrameworkExtensions.xml 文件中验证技术配置文件中的第一个节点(请注意,在 TrustFrameworkBase.xml 中,AAD-UserWriteUsingLogonEmail 已经存在。我不想更改基础,因为它不推荐。

      在 TrustFrameworkExtensions.xml 中(用于 LocalAccountsSignUpWithLogonEmail)

      <ValidationTechnicalProfiles>
          <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
          <ValidationTechnicalProfile ReferenceId="REST-API-SignUp" />
      </ValidationTechnicalProfiles>
      

      在 TrustFrameworkBase.xml 中(用于 LocalAccountsSignUpWithLogonEmail)

       <ValidationTechnicalProfiles>
          <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail"/> 
       </ValidationTechnicalProfiles>
      

      但是我认为 AAD-UserWriteUsingLogonEmail 被调用了两次。一次在扩展中,然后在基础中一次。

      真的有人知道这种继承或覆盖是如何工作的吗?如果您在扩展 xml 中定义某些内容,它会覆盖还是合并?如果是,按什么顺序?似乎首先调用了基本节点,所以这就是没有填充 oid 的原因。但是当你把它作为第一个节点放在扩展中时(你希望它覆盖基础),基础被再次调用。无论如何要更改顺序或说“我希望它替换(覆盖)基础中的内容?它是否合并?没有关于基础策略如何工作的文档。

      我会尝试按照建议更改旅程,但如果有人可以回答,我仍然想知道基本政策如何运作

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-24
        • 1970-01-01
        相关资源
        最近更新 更多