【问题标题】:In Azure B2C Custom Policies, how do I display more than 2 distinct validation messages for validations that depend on Validation Technical Profiles?在 Azure B2C 自定义策略中,如何为依赖于验证技术配置文件的验证显示超过 2 条不同的验证消息?
【发布时间】:2020-06-10 16:33:32
【问题描述】:

场景

在我的注册流程中,我需要显示:

  • 电子邮件地址字段和确认电子邮件地址字段
  • 密码字段和确认密码字段

我必须验证:

  • 在电子邮件地址字段中输入的文本与在确认电子邮件地址字段中输入的文本相匹配
  • 密码字段中输入的文本与确认密码字段中输入的文本相匹配
  • 为用户输入的电子邮件地址在 Azure B2C 中尚不存在

这些验证应显示在现有表单中,而不是新页面中。

作为验证技术配置文件的输出结果,我能够内联显示验证消息的唯一方法是使用两个内置断言,AssertStringClaimsAreEqual(用于电子邮件和密码比较)和 AssertBooleanClaimIsEqualToValue(用于现有用户检查)。这些导致调用声明提供程序技术配置文件中定义的消息在断言失败时显示。

问题

我有三个需要不同消息的错误案例,我只能定义和显示两个消息。目前,我正在通过显示“电子邮件和确认电子邮件,或密码和确认密码不匹配”来解决这个问题。对于失败的文本比较和“此电子邮件地址已被使用,请登录”。对于现有的用户案例。现有的用户案例很好,但我会将单个文本比较消息描述为“好的,但并不真正符合接受标准”和“我不敢相信没有更好的方法来做到这一点”。

任何帮助都将不胜感激。

当前代码片段

相关的验证技术简介:

    <TechnicalProfile Id="EmailMatchValidator">
      <DisplayName>Check if email and confirm email match</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      <InputClaimsTransformations>
        <InputClaimsTransformation ReferenceId="DoEmailsMatch"/>
      </InputClaimsTransformations>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="emailsMatch" Required="true"/>
      </OutputClaims>
    </TechnicalProfile>

    <TechnicalProfile Id="PasswordMatchValidator">
      <DisplayName>Check if password and confirm password match</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      <InputClaimsTransformations>
        <InputClaimsTransformation ReferenceId="DoPasswordsMatch"/>
      </InputClaimsTransformations>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="passwordsMatch" Required="true"/>
      </OutputClaims>
    </TechnicalProfile>

    <TechnicalProfile Id="UserExistsValidator">
      <DisplayName>Asset if user exists</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="userExists"/>
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="userExists" Required="true"/>
      </OutputClaims>
      <OutputClaimsTransformations>
        <OutputClaimsTransformation ReferenceId="DoesUserExist"/>
      </OutputClaimsTransformations>
    </TechnicalProfile>

这些技术配置文件引用输出声明转换,如下所示:

  <ClaimsTransformation Id="DoEmailsMatch" TransformationMethod="AssertStringClaimsAreEqual">
    <InputClaims>
      <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="inputClaim1"/>
      <InputClaim ClaimTypeReferenceId="confirmEmail" TransformationClaimType="inputClaim2"/>
    </InputClaims>
    <InputParameters>
      <InputParameter Id="stringComparison" DataType="string" Value="ordinalIgnoreCase"/>
    </InputParameters>
  </ClaimsTransformation>

  <ClaimsTransformation Id="DoPasswordsMatch" TransformationMethod="AssertStringClaimsAreEqual">
    <InputClaims>
      <InputClaim ClaimTypeReferenceId="password" TransformationClaimType="inputClaim1"/>
      <InputClaim ClaimTypeReferenceId="confirmpassword" TransformationClaimType="inputClaim2"/>
    </InputClaims>
    <InputParameters>
      <InputParameter Id="stringComparison" DataType="string" Value="ordinalIgnoreCase"/>
    </InputParameters>
  </ClaimsTransformation>

  <ClaimsTransformation Id="DoesUserExist" TransformationMethod="AssertBooleanClaimIsEqualToValue">
    <InputClaims>
      <InputClaim ClaimTypeReferenceId="userExists" TransformationClaimType="inputClaim"/>
    </InputClaims>
    <InputParameters>
      <InputParameter Id="valueToCompareTo" DataType="boolean" Value="false"/>
    </InputParameters>
  </ClaimsTransformation>

DoEmailsMatch 和 DoPasswordsMatch 非常简单,使用 AssertStringClaimsAreEqual 内置断言来显示在调用 Claim Provider Technical Profile 的元数据中定义的消息:

<Item Key="UserMessageIfClaimsTransformationStringsAreNotEqual">Email and confirm email, or password and confirm password do not match.</Item>

DoesUserExist 依赖于 AssertBooleanClaimIsEqualToValue,这意味着它需要一个布尔值来决定是否显示元数据中定义的其他消息:

<Item Key="UserMessageIfClaimsTransformationBooleanValueIsNotEqual">This email address is already in use, please sign in.</Item>

设置该布尔值的代码可能超出了此问题的范围,但简而言之,它是通过读取 AAD 数据库来设置的,该数据库在声明中返回匹配的用户主体名称,或者根本没有声明。这会使用 DoesClaimExist 进行声明转换,以设置布尔值 userExists 声明,由上述 DoesUserExist 使用。

【问题讨论】:

    标签: azure-ad-b2c


    【解决方案1】:

    对于第三个,改为执行 AAD 读取操作,它有一个内置的错误消息,用于指示何时存在。

    https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-technical-profile#ui-elements

    您可以在默认注册流程的 AAD B2C 入门包中找到它。

    对于密码匹配,使用密码和重新输入密码,使用内置方式 https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/blob/master/LocalAccounts/TrustFrameworkBase.xml#L648

    现在您应该只需要 1 个声明转换来进行电子邮件匹配。

    【讨论】:

    • 嗨@Jas Suri,谢谢!关于使用内置密码验证而不是手动验证的提示给了我我需要的东西。我将密码重新输入字段命名为“confirmPassword”而不是“reenterPassword”,但没有意识到 reenterPassword 背后隐藏着神奇的逻辑。
    • 我确实发生了另一件事,但这对我来说不再是问题:如果主体已经存在,我不确定 AADRead 操作是否会引发错误。我只能从 AADWrite 获取 RaiseErrorIfClaimsPrincipalAlreadyExists。
    • 是的,您在阅读操作评论上是对的,需要使用声明转换。
    • 只是想确认一下。不管怎样,我的问题现在已经解决了,再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 2019-08-20
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    相关资源
    最近更新 更多