微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Azure AD B2C-在上一个业务流程步骤中的输入声明中填充电子邮件,并且Verify.email无法正常工作

如何解决Azure AD B2C-在上一个业务流程步骤中的输入声明中填充电子邮件,并且Verify.email无法正常工作

协调的第一步是登录-接收电子邮件输出声明 第二步是电子邮件验证-我想从登录中填充电子邮件,然后使用电子邮件OTP进行验证。

问题- 如果填充了电子邮件,则验证按钮不会出现。 如果出现“验证”按钮,则表明电子邮件未填充。

解决方法

我可以通过在DisplayClaim中使用DisplayControl而不是在OutputClaim中使用Verified.Email来解决此用例。

首先在BuildingBlocks中定义这两个属性,ClaimsSchema:

<BuildingBlocks>

  <!-- ClaimsSchema -->

  <ClaimsTransformations>
    <ClaimsTransformation Id="CopyEmailAddress" TransformationMethod="CopyClaim">
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="inputClaim"/>
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="readOnlyEmail" TransformationClaimType="outputClaim"/>
      </OutputClaims>
    </ClaimsTransformation>
  </ClaimsTransformations>

  <!-- ContentDefinitions,DisplayControls,etc. -->

</BuildingBlocks>

我们将把email属性复制到readOnlyEmail属性中,以便我们可以在屏幕上显示它,并且在验证电子邮件一次性密码(OTP)时将使用verifyCode属性。在这里陪我。

在BuildingBlocks中定义一个ClaimsTransformation,并将ClaimsTransformations通过电子邮件复制到readOnlyEmail。

<BuildingBlocks>

  <!-- ClaimsSchema,ClaimsTransformations -->

  <ContentDefinitions>
    <ContentDefinition Id="api.selfasserted">
      <LoadUri>~/tenant/templates/AzureBlue/selfAsserted.cshtml</LoadUri>
      <RecoveryUri>~/common/default_page_error.html</RecoveryUri>
      <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.0.0</DataUri>
      <Metadata>
        <Item Key="DisplayName">Collect information from user page</Item>
      </Metadata>
    </ContentDefinition>
  </ContentDefinitions>

  <!-- DisplayControls,etc. -->

</BuildingBlocks>

修改ContentDefinition中api.selfasserted的DataUri元素,使其版本为2.0.0,并包含“ contract”标记。您必须执行此操作才能允许DisplayClaims工作。

api.selfasserted ContentDefinition现在应如下所示:

<BuildingBlocks>

  <!-- ClaimsSchema,ClaimsTransformations,ContentDefinitions,etc -->

  <DisplayControls>
    <DisplayControl Id="emailVerificationControl" UserInterfaceControlType="VerificationControl">
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="readOnlyEmail" />
      </InputClaims>
      <DisplayClaims>
        <DisplayClaim ClaimTypeReferenceId="readOnlyEmail" />
        <DisplayClaim ClaimTypeReferenceId="verificationCode" ControlClaimType="VerificationCode" />
      </DisplayClaims>
      <Actions>
        <Action Id="SendCode">
          <ValidationClaimsExchange>
            <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="AadSspr-SendCode" />
          </ValidationClaimsExchange>
        </Action>
        <Action Id="VerifyCode">
          <ValidationClaimsExchange>
            <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="AadSspr-VerifyCode" />
          </ValidationClaimsExchange>
        </Action>
      </Actions>
    </DisplayControl>
  </DisplayControls>

</BuildingBlocks>

这里唯一的变化是对ContentDefinition中的DataUri元素。请注意,我们对其进行了更新,以包含“ contract”一词,并且其版本现在为2.0.0。

然后在BuildingBlocks,使用我们的readOnlyEmail的DisplayControl以及verficationCode ClaimTypes中定义一个DisplayControl:

<TechnicalProfile Id="AadSspr-SendCode">
  <DisplayName>Send Code</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.AadSsprProtocolProvider,Web.TPEngine,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null" />
  <Metadata>
    <Item Key="Operation">SendCode</Item>
  </Metadata>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="readOnlyEmail" PartnerClaimType="emailAddress"/>
  </InputClaims>
</TechnicalProfile>

<TechnicalProfile Id="AadSspr-VerifyCode">
  <DisplayName>Verify Code</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.AadSsprProtocolProvider,PublicKeyToken=null" />
  <Metadata>
    <Item Key="Operation">VerifyCode</Item>
  </Metadata>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="verificationCode" PartnerClaimType="verificationCode" />
    <InputClaim ClaimTypeReferenceId="readOnlyEmail" PartnerClaimType="emailAddress"/>
  </InputClaims>
</TechnicalProfile>

请注意,此处我们显示的是readOnlyEmail,第二个DisplayClaim用于VerificationCode是用于在将OTP发送到您的电子邮件后收集该OTP。

还要注意指向我们尚未定义的TechnicalProfiles的操作。它们对应于屏幕上的按钮,并将发送电子邮件并验证代码。接下来定义它们。您可以将它们放在您想要的任何ClaimsProvider中:

<TechnicalProfile Id="SelfAsserted-VerifyEmail">
  <DisplayName>Verify Email</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider,PublicKeyToken=null" />
  <Metadata>
    <Item Key="ContentDefinitionReferenceId">api.selfasserted</Item>
  </Metadata>
  <IncludeInSso>false</IncludeInSso>
  <InputClaimsTransformations>
    <InputClaimsTransformation ReferenceId="CopyEmailAddress" />
  </InputClaimsTransformations>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="email" />
    <InputClaim ClaimTypeReferenceId="readOnlyEmail" />
  </InputClaims>
  <DisplayClaims>
    <DisplayClaim DisplayControlReferenceId="emailVerificationControl" />
  </DisplayClaims>
</TechnicalProfile>

这些技术资料正在利用AadSsprProtocolProvider来发送和验证代码。 MS在这里有很好的文档:https://docs.microsoft.com/en-us/azure/active-directory-b2c/aad-sspr-technical-profile

快到了。现在,我们创建一个SelfAssertedAttributeProvider TechnicalProfile,以利用我们的新DisplayClaim进行内联验证。

在您想要的任何ClaimsProvider中创建此TechnicalProfile:

<OrchestrationStep Order="X" Type="ClaimsExchange">
  <ClaimsExchanges>
    <ClaimsExchange Id="SelfAsserted-VerifyEmail-CE" TechnicalProfileReferenceId="SelfAsserted-VerifyEmail"/>
  </ClaimsExchanges>
</OrchestrationStep>

此TechnicalProfile将以电子邮件作为输入,将其复制到具有InputClaimsTransformation的readOnlyEmail中,然后在新的emailVerificationControl DisplayClaim中使用readOnlyEmail。然后,该emailVerficationControl会向用户显示电子邮件的readOnly值,具有用于发送代码的按钮,然后能够在发送代码后对其进行验证。

您需要做的最后一件事是在UserJourney的OrchestrationSteps中使用此新的TechnicalProfile,如下所示:

{{1}}

这项技术可以解决您遇到麻烦的用例。

,

我们遇到了同样的问题。 需要自动填写电子邮件并进行验证。 问题在于,填充的值会立即被视为已验证。

所以我们不得不间接地做些。 首先,我们定义了一个“原始电子邮件”声明:

<ClaimType Id="originalEmail">
  <DisplayName>Original email</DisplayName>
  <DataType>string</DataType>
  <UserInputType>Readonly</UserInputType>
</ClaimType>

然后,注册技术资料定义了2个输入声明,2个输入转换和1个输出声明(以及所有其他内容):

<InputClaimsTransformations>
  <InputClaimsTransformation ReferenceId="SetOriginalEmailFromEmail" />
  <InputClaimsTransformation ReferenceId="SetEmailToNull" />
</InputClaimsTransformations>
<InputClaims>
  <InputClaim ClaimTypeReferenceId="email" />
  <InputClaim ClaimTypeReferenceId="originalEmail" />
</InputClaims>
<OutputClaims>
  <OutputClaim ClaimTypeReferenceId="originalEmail" />
</OutputClaims>

第一个索赔转换将值从电子邮件复制到originalEmail:

<ClaimsTransformation Id="SetOriginalEmailFromEmail" TransformationMethod="FormatStringClaim">
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="inputClaim" />
  </InputClaims>
  <InputParameters>
    <InputParameter Id="stringFormat" DataType="string" Value="{0}" />
  </InputParameters>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="originalEmail" TransformationClaimType="outputClaim" />
  </OutputClaims>
</ClaimsTransformation>

第二次转换将重置电子邮件声明:

<ClaimsTransformation Id="SetEmailToNull" TransformationMethod="NullClaim">
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="email" TransformationClaimType="claim_to_null" />
  </OutputClaims>
</ClaimsTransformation>

这样,电子邮件首先将显示为空,原始电子邮件将在其旁边的隐藏字段中显示。 然后,您可以在自定义UI中使用JavaScript在加载时复制值:

(function () {
    setTimeout(function () {
        copyOriginalEmailToEmail();
    },500);

    function copyOriginalEmailToEmail() {
        var originalEmailField = document.getElementById('originalEmail');
        var originalEmail = originalEmailField && originalEmailField.value;
        if (originalEmail) {
            document.getElementById('email').value = originalEmail;
        }
    }
}());

很黑,但是效果很好。 立即设置该值也会导致“发送代码”按钮也消失,所以这就是延迟的原因。

如果有更简便的方法,我也想知道:D

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。