3

我有一个注册流程,它运行良好并且是多步骤的:

  1. 联系方式
  2. 确认
  3. 密码

现在的流程是,在完成所有步骤后,将创建一个新用户,如果用户名已经存在,那么在最后一步我会收到一条错误消息,指出用户已经存在。现在我需要改变这个流程。输入联系方式(电子邮件)后,我想检查该用户是否存在。如果存在,那么我需要显示在第一步本身的最后一步中显示的错误消息,并阻止旅程进入下一步。

为此,我所做的是:

创建了一个使用电子邮件读取用户详细信息的 TP,并将其作为第一步的验证技术配置文件:

<TechnicalProfile Id="AAD-CheckUserExist">
                    <Metadata>
                        <Item Key="Operation">Read</Item>                        
                        <Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">true</Item>
                    </Metadata>
                    <IncludeInSso>false</IncludeInSso>
                    <InputClaims>                       
                        <InputClaim ClaimTypeReferenceId="email" PartnerClaimType="signInNames.emailAddress" />                        
                    </InputClaims>
                    <OutputClaims>
                        <!-- Required claims -->
                        <OutputClaim ClaimTypeReferenceId="objectId" />
                        <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" />
                        <!-- Optional claims -->
                        <OutputClaim ClaimTypeReferenceId="userPrincipalName" />
                        <OutputClaim ClaimTypeReferenceId="displayName" />
                        <OutputClaim ClaimTypeReferenceId="accountEnabled" />
                        <OutputClaim ClaimTypeReferenceId="otherMails" />
                        <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress"/>
                        <OutputClaim ClaimTypeReferenceId="signInNames.phoneNumber"/>
                        <OutputClaim ClaimTypeReferenceId="givenName" />
                        <OutputClaim ClaimTypeReferenceId="surname" />
                    </OutputClaims>
                    <IncludeTechnicalProfile ReferenceId="AAD-Common" />
                </TechnicalProfile>

并添加<Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">true</Item><Metadata>.

以下是验证配置文件部分:

 <ValidationTechnicalProfiles>
    <ValidationTechnicalProfile ReferenceId="AAD-CheckUserExist" ContinueOnError="false"/>
 </ValidationTechnicalProfiles>

但它没有按预期工作,我在第一步单击下一步后尝试与现有用户一起移动验证步骤而没有任何错误。

4

1 回答 1

6

RaiseErrorIfClaimsPrincipalAlreadyExists仅在Operation 为Write时有效。

在读取操作之后,仅当用户已经存在时才会填充 objectId 声明。你必须阅读RaiseErrorIfClaimsPrincipalDoesNotExist = false然后你可以使用 ClaimTransformations 和 ValidationTechnicalProfiles 来阻止 UserJourney if objectId != null

编辑:示例

我在 AAD Claims Provider 下创建了AAD-UserReadUsingEmailAddress-RaiseIfExists技术配置文件

    <TechnicalProfile Id="AAD-UserReadUsingEmailAddress-RaiseIfExists">
      <Metadata>
        <Item Key="Operation">Read</Item>
        <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">false</Item>
      </Metadata>
      <IncludeInSso>false</IncludeInSso>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" PartnerClaimType="signInNames.emailAddress" Required="true" />
      </InputClaims>
      <OutputClaims>
        <!-- Required claims -->
        <OutputClaim ClaimTypeReferenceId="objectId" DefaultValue="NOTFOUND" />
        <OutputClaim ClaimTypeReferenceId="objectIdNotFound" DefaultValue="NOTFOUND" AlwaysUseDefaultValue="true" />
      </OutputClaims>
      <OutputClaimsTransformations>
        <OutputClaimsTransformation ReferenceId="AssertObjectIdObjectIdNotFoundAreEqual" />
      </OutputClaimsTransformations>
      <IncludeTechnicalProfile ReferenceId="AAD-Common" />
    </TechnicalProfile>

如您所见,我正在使用电子邮件声明来搜索用户并仅获取 objectId。请注意RaiseErrorIfClaimsPrincipalDoesNotExist = false以及 objectId 的 defaultValue 为 NOTFOUND 的事实。根据 AlwaysUseDefaultValue="true",objectIdNotFound 将始终为 NOTFOUND

objectIdNotFound 是一个简单的字符串声明

  <ClaimType Id="objectIdNotFound">
    <DisplayName>Used for comparison</DisplayName>
    <DataType>string</DataType>
  </ClaimType>

AssertObjectIdObjectIdNotFoundAreEqual OutputClaim转换如下:

   <ClaimsTransformation Id="AssertObjectIdObjectIdNotFoundAreEqual" TransformationMethod="AssertStringClaimsAreEqual">
    <InputClaims>
      <InputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="inputClaim1" />
      <InputClaim ClaimTypeReferenceId="objectIdNotFound" TransformationClaimType="inputClaim2" />
    </InputClaims>
    <InputParameters>
      <InputParameter Id="stringComparison" DataType="string" Value="ordinalIgnoreCase" />
    </InputParameters>
  </ClaimsTransformation>

然后我在我的 SelfAsserted TechnicalProfile 中使用AAD-UserReadUsingEmailAddress-RaiseIfExists作为验证 TechnicalProfile

    <TechnicalProfile Id="LocalAccountSignUpWithLogonEmail-CheckEmailAlreadyExists">
      <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">Next</Item>
        <Item Key="UserMessageIfClaimsTransformationStringsAreNotEqual">There is another user with this email address</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />
      </OutputClaims>
      <ValidationTechnicalProfiles>
        <ValidationTechnicalProfile ReferenceId="AAD-UserReadUsingEmailAddress-RaiseIfExists" />
      </ValidationTechnicalProfiles>
    </TechnicalProfile>

使用此设置,当您单击“继续”时,将执行验证技术配置文件,如果已经有用户使用插入的电子邮件,则会引发错误。发生这种情况是因为如果找到用户,objectId 将是一个 guid,它不会等于“NOTFOUND”。您可以通过UserMessageIfClaimsTransformationStringsAreNotEqual元数据更改错误消息。

HTH,F.

于 2020-01-23T16:50:50.633 回答