如何解决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 举报,一经查实,本站将立刻删除。