skip to Main Content

I would need to split the user registration into two screens as follows

  1. Will capture the email, password and confirm password
  2. User name and other details.

Here it allows creating the user where the password fields are being captures.
but I would need to create an account in Azure in the second step but getting 500 error.It is not even showing the Signup First screen.

I’ve already looked into this https://github.com/azure-ad-b2c/samples/tree/master/policies/split-email-verification-and-signup but didn’t help.


    <TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email">
              <DisplayName>Local Account Signin</DisplayName>
              <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
              <Metadata>
                         <Item Key="SignUpTarget">SignUpWithLogonEmailExchange</Item>
                <Item Key="setting.operatingMode">Email</Item>
                <Item Key="ContentDefinitionReferenceId">api.selfasserted.profileupdate</Item>
                <Item Key="setting.forgotPasswordLinkLocation">AfterLabel</Item>
                <Item Key="setting.showCancelButton">true</Item>
                <Item Key="setting.forgotPasswordLinkOverride">ForgotPasswordExchange</Item>
              </Metadata>
              <IncludeInSso>false</IncludeInSso>
              <InputClaims>
                <InputClaim ClaimTypeReferenceId="signInName" DefaultValue="{Claim:email}" />
              </InputClaims>
              <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="signInName" Required="true" />
                <OutputClaim ClaimTypeReferenceId="password" Required="true" />
                <OutputClaim ClaimTypeReferenceId="objectId" />
                <OutputClaim ClaimTypeReferenceId="authenticationSource" />
                <OutputClaim ClaimTypeReferenceId="newUser" DefaultValue="false" AlwaysUseDefaultValue="true" />
              </OutputClaims>
              <ValidationTechnicalProfiles>
                <ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
              </ValidationTechnicalProfiles>
              <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
            </TechnicalProfile>

I have removed
<ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
from the LocalAccountSignUpWithLoginEmail and added under SignUp second screen technical profile. After removing it is not even show the Signup screen.

    <TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
              <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">Create</Item>
                <Item Key="setting.showCancelButton">false</Item>
                <!-- <Item Key="EnforceEmailVerification">false</Item> -->
              </Metadata>
              <CryptographicKeys>
                <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
              </CryptographicKeys>
              <InputClaims>
                <InputClaim ClaimTypeReferenceId="email" />
              </InputClaims>
              <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="objectId" />
                <OutputClaim ClaimTypeReferenceId="signup_company_name" Required="true" />
                <OutputClaim ClaimTypeReferenceId="email" Required="true" />
                <OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />
                <OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
                <OutputClaim ClaimTypeReferenceId="signup_number_of_events" />
                <OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" />
                <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccount" AlwaysUseDefaultValue="true" />
                <OutputClaim ClaimTypeReferenceId="newUser" />
              </OutputClaims>
              <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
            </TechnicalProfile>

This is my User Journey

<UserJourneys>
    <UserJourney Id="SignUpOrSignIn">
        <OrchestrationSteps>
            <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
                <ClaimsProviderSelections>
                    <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
                     <ClaimsProviderSelection TargetClaimsExchangeId="GoogleExchange" />
                     <ClaimsProviderSelection TargetClaimsExchangeId="LinkedInExchange" />
                     <ClaimsProviderSelection TargetClaimsExchangeId="TwitterExchange" />
                </ClaimsProviderSelections>
                <ClaimsExchanges>
                    <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
                </ClaimsExchanges>
            </OrchestrationStep>
            <OrchestrationStep Order="2" Type="ClaimsExchange">
                <Preconditions>
                    <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                        <Value>objectId</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                </Preconditions>
                <ClaimsExchanges>
                     <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
                     <ClaimsExchange Id="GoogleExchange" TechnicalProfileReferenceId="Google-OAuth2" />
                     <ClaimsExchange Id="LinkedInExchange" TechnicalProfileReferenceId="LinkedIn-OAuth2" />
                     <ClaimsExchange Id="TwitterExchange" TechnicalProfileReferenceId="Twitter-OAuth1" />
                </ClaimsExchanges>
            </OrchestrationStep>
            <OrchestrationStep Order="3" Type="ClaimsExchange">
                <Preconditions>
                    <Precondition Type="ClaimsExist" ExecuteActionsIf="false">
                        <Value>objectId</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                    <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
                        <Value>newUser</Value>
                        <Value>true</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                    <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                        <Value>authenticationSource</Value>
                        <Value>socialIdpAuthentication</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                    <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                        <Value>isForgotPassword</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                </Preconditions>
                <ClaimsExchanges>
                    <ClaimsExchange Id="SignUpSecondStepExchange" TechnicalProfileReferenceId="SignUpSecondStepProfile" />
                </ClaimsExchanges>
            </OrchestrationStep>
            <!-- Show self-asserted page only if the directory does not have the user account already (i.e. we do not have an objectId). 
          This can only happen when authentication happened using a social IDP. If local account was created or authentication done
          using ESTS in step 2, then an user account must exist in the directory by this time. -->
            <OrchestrationStep Order="4" Type="ClaimsExchange">
                <Preconditions>
                    <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                        <Value>objectId</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                    <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
                        <Value>authenticationSource</Value>
                        <Value>socialIdpAuthentication</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                    <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                        <Value>isForgotPassword</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                </Preconditions>
                <ClaimsExchanges>
                    <ClaimsExchange Id="SelfAsserted-Social" TechnicalProfileReferenceId="SelfAsserted-Social" />
                </ClaimsExchanges>
            </OrchestrationStep>
            <OrchestrationStep Order="5" Type="ClaimsExchange">
                <Preconditions>
                    <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                        <Value>objectId</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                    <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                        <Value>authenticationSource</Value>
                        <Value>socialIdpAuthentication</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                </Preconditions>
                <ClaimsExchanges>
                    <ClaimsExchange Id="SignUpWithLogonEmailExchange_Password" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
                </ClaimsExchanges>
            </OrchestrationStep>
            <!-- This step reads any user attributes that we may not have received when in the token. -->
            <OrchestrationStep Order="11" Type="ClaimsExchange">
                <ClaimsExchanges>
                    <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
                </ClaimsExchanges>
            </OrchestrationStep>
            <!-- The previous step (SelfAsserted-Social) could have been skipped if there were no attributes to collect 
             from the user. So, in that case, create the user in the directory if one does not already exist 
             (verified using objectId which would be set from the last step if account was created in the directory. -->
            <OrchestrationStep Order="6" Type="ClaimsExchange">
                <Preconditions>
                    <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                        <Value>objectId</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                    <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
                        <Value>authenticationSource</Value>
                        <Value>socialIdpAuthentication</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                    <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
                        <Value>identityProvider</Value>
                        <Value>linkedin.com</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                </Preconditions>
                <ClaimsExchanges>
                     <ClaimsExchange Id="AADUserWrite" TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityId" />
                </ClaimsExchanges>
            </OrchestrationStep>
            <OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
        </OrchestrationSteps>
        <ClientDefinition ReferenceId="DefaultWeb" />
    </UserJourney>
    </UserJourneys>
    

Note: When I keeping the <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
under the LocalAccountSignUpWithLoginEmail technical profile, the account is created during the first step and then displaying the second screen.

Can someone help how do we split the registration screens?

2

Answers


  1. I believe your issue arises due to how password claims are handled. Any claim with the password user input type can only be used in a self-asserted profile’s validation profiles, as detailed here. You can’t get the user’s password in one step, then pass it on to the next, it has to be written somewhere (ideally to the user account) in a validation technical profile.

    So, you’ll have to do two writes, one with the email and password, then the second with other information. If you are worried about users exiting the signup process part way through, you may want to set a flag after the first write to mark that while the account exists, additional information will need to be added when they next login, and then have that flag be unset after the user fills out the additional information.

    Your other option is to store the user’s password elsewhere using a REST API validation technical profile, then retrieve and write that password to the user account in the next step, though I would not recommend this approach.

    Edit, workarounds:

    I wouldn’t recommend doing this for security reasons, but a similar question here has answers that use workarounds to store the password in other claims to pass it on to the next step. However, this could lead to security issues with Application Insights logging the password.

    If you really want to do a two-step sign up and only a single write, you could probably also just reverse the order. Get the user info claims, then the email and password.

    Login or Signup to reply.
  2. Before giving the split description, please note that password claims are not allowed to pass to next step/ technical profile. If you do like that user will get created but password won’t be written and sign in might be get blocked. So as per the above answer you have to copy the password and use it in the step2 (I haven’t done that here.)

    I’m not sure what exactly is the issue you are facing. But I did the signup split just like you mentioned in your requirement. I’ve used default custom policy starter pack. Please see my user journey and signup steps that I’ve used.

    <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
          <ClaimsProviderSelections>
            <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
            <ClaimsProviderSelection TargetClaimsExchangeId="ForgotPasswordExchange" />
            <ClaimsProviderSelection TargetClaimsExchangeId="SignUpWithLogonEmailExchange" />
          </ClaimsProviderSelections>
          <ClaimsExchanges>
            <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
          </ClaimsExchanges>
        </OrchestrationStep>
    
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail_step1" />
            <ClaimsExchange Id="ForgotPasswordExchange" TechnicalProfileReferenceId="ForgotPassword" />
          </ClaimsExchanges>
        </OrchestrationStep>
    
        <OrchestrationStep Order="3" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="SignUpWithLogonEmailExchange_Step2" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail_step2" />
          </ClaimsExchanges>
        </OrchestrationStep>
    

    Technical profiles

    <TechnicalProfile Id="LocalAccountSignUpWithLogonEmail_step1">
          <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>
          </Metadata>
          <CryptographicKeys>
            <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
          </CryptographicKeys>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="email" />
          </InputClaims>
          <OutputClaims>
            <!-- <OutputClaim ClaimTypeReferenceId="objectId" /> -->
            <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />
            <OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />
            <OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
            <OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" />
            <OutputClaim ClaimTypeReferenceId="newUser" DefaultValue="true"/>
          </OutputClaims>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
        </TechnicalProfile>
    
    
    <TechnicalProfile Id="LocalAccountSignUpWithLogonEmail_step2">
          <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>
          </Metadata>
          <CryptographicKeys>
            <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
          </CryptographicKeys>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="email" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" />
            <!-- Optional claims, to be collected from the user -->
            <OutputClaim ClaimTypeReferenceId="displayName" />
            <OutputClaim ClaimTypeReferenceId="givenName" />
            <OutputClaim ClaimTypeReferenceId="surName" />
          </OutputClaims>
          <ValidationTechnicalProfiles>
            <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
          </ValidationTechnicalProfiles>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
        </TechnicalProfile>
    

    Hope this helps!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search