0

I got a request to verify that an email has not been used before sending the verification code in our Sign Up custom policy. In our Password reset policy we use DisplayControl to check if the password exist before sending the OTP code and only send the OTP if the email has already been registered. However, I need to do the opposite for the registration process, only send the code if the email has NOT been registered.

I tried to use the following:

      <DisplayControl Id="emailVerificationControlSignUp" UserInterfaceControlType="VerificationControl">
    <InputClaims>
      <InputClaim ClaimTypeReferenceId="emailAddress" />
    </InputClaims>
    <DisplayClaims>
      <DisplayClaim ClaimTypeReferenceId="emailAddress" ControlClaimType="Email" Required="true" />
      <DisplayClaim ClaimTypeReferenceId="verificationCode" ControlClaimType="VerificationCode" Required="true" />
    </DisplayClaims>
    <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="azureMfaSessionId" />
    </OutputClaims>
    <Actions>
      <!--Before generating and sending an OTP, we first take the users email and lookup the directory for a user. If a user is returned we will have the objectId claim in the claimbag-->
      <Action Id="SendCode">
        <ValidationClaimsExchange>
          <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="AAD-UserReadUsingEmailAddress-emailAdressExist" ContinueOnError="true" ContinueOnSuccess="false" />
          <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="AadSspr-SendCode">
            <Preconditions>
              <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                <Value>objectId</Value>
                <Action>SkipThisValidationTechnicalProfile</Action>
              </Precondition>
            </Preconditions>
          </ValidationClaimsExchangeTechnicalProfile>
        </ValidationClaimsExchange>
      </Action>
      <Action Id="VerifyCode">
        <ValidationClaimsExchange>
          <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="AadSspr-VerifyCode" />
        </ValidationClaimsExchange>
      </Action>
    </Actions>
  </DisplayControl>

and this TechnicalProfile

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

What happen is that the OTP is indeed only sent if the email has not been registered, however, the DisplayControl always change to show the "verify code/Send new code" buttons, even if the email has been registered. So, in the end, what happen is that if the email has been registered, the user doesn't get the OTP, only if the email has NOT been registered. However, nothing on the screen tells the user that.

enter image description here Email has been registered, user should see error message and not the verify/send new code buttons

How can I fix this DisplayControl?

Thank you

1 Answers1

0

thank you for reaching out. From the DisplayControl element shared above, I can see that the user is already getting ready from this line:

<ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="AAD-UserReadUsingEmailAddress-emailAdressExist" ContinueOnError="true" ContinueOnSuccess="false" />

After the user gets read, check if objectid exists - > call claimTransform

Note: This approach is not recommended because it can be used to harvest emails. The recommended approach sending email in all cases for sign up.

  • Hello! I've tried this approach, but no matter how I try to change it, I still get same or similar issue. Please, could you provide some further explanation about how to implement it? I read the documentation in MS website, but it wasn't very helpful. – Henrique Belotto Feb 17 '21 at 22:03