Azure AD B2C Reset Password Custom Policy with confirmation screen

1.5k views Asked by At

I have set up a Sign-In custom policy in Azure AD B2C in order to customise the GUI dynamic content during the login flow and customise the branding based on certain scenarios. This sign-in policy displays a "Forgot your password?" link that is handled by my application to initiate the flow for another custom Password Reset policy.

In the standard Password Reset policies provided by B2C, once the user has reset the password, an additional screen appears indicating that the password has been successfully changed and provides a link to re-execute the sign-in policy. With the custom policy, the redirect url is immediately called after the password has been reset.

Is it possible to configure an additional step to the Password Reset policy flow with a screen that shows a confirmation message?

1

There are 1 answers

1
Steve On

I've been struggling with this for days as well. I've managed to get it working by adding the following to the Extensions file.

  1. Add step 3 to the existing OrchestrationSteps for the PasswordReset UserJourney
<UserJourney Id="PasswordReset">
  <OrchestrationSteps>
    <OrchestrationStep Order="1" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="2" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="3" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="ShowSuccess" TechnicalProfileReferenceId="LocalAccountWritePasswordChanged" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
  </OrchestrationSteps>
  <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>

  1. Add this ClaimType in BuildingBlocks/ClaimsSchema
  <ClaimType Id="justResetPassword">
    <DisplayName>justResetPassword</DisplayName>
    <DataType>boolean</DataType>
    <UserHelpText>Indicates whether the user just reset their password via the forgot password feature.</UserHelpText>
    <UserInputType>Button</UserInputType>
  </ClaimType>

  1. Add the above mentioned new TechnicalProfile: LocalAccountWritePasswordChanged
    <TechnicalProfile Id="LocalAccountWritePasswordChanged">
      <DisplayName>Changed password</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ContentDefinitionReferenceId">api.passwordchangesuccess</Item>
        <Item Key="language.button_continue">Back to Login</Item>
        <Item Key="language.initial_intro">Ready to login again...</Item>
        <Item Key="language.verifying_blurb">Preparing login screen.</Item>
        <!-- TODO: Hide cancel button -->
      </Metadata>
      <CryptographicKeys>
        <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
      </CryptographicKeys>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="objectId" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="justResetPassword" DefaultValue="true" />
      </OutputClaims>
    </TechnicalProfile>

  1. Modify your Relying Party file to also have an outputClaim of the new type justResetPassword
<OutputClaim ClaimTypeReferenceId="justResetPassword" />

I think the trick is that this new technical profile has an outputclaim of justResetPassword, so it will fire to try and capture that value. As it's datatype is button though it doesn't display. This bit I am not very clear on, but as it is working and it took me this long to get here, I'm not going to question it too much.

You may notice this new technical profile references a ContentDefinition of api.passwordchangesuccess. This is a custom content definition that I created myself to provide a nicer custom heading for the "Password reset message". You may be able to utilize the ContentDefinition api.selfasserted instead if you don't need too much customisation of the success page.

Final result after resetting password: Screenshot