Set up a password reset flow in Azure Active Directory B2C

Before you begin, use the selector above to choose the type of policy you’re configuring. Azure AD B2C offers two methods of defining how users interact with your applications: through predefined user flows, or through fully configurable custom policies. The steps required in this article are different for each method.

Password reset flow

The sign-up and sign-in journey allows users to reset their own password using the Forgot your password? link. The password reset flow involves the following steps:

  1. From the sign-up and sign-in page, the user clicks the Forgot your password? link. Azure AD B2C initiates the password reset flow.
  2. The user provides and verifies their email address with a Timed One Time Passcode.
  3. The user can then enter a new password.

Password reset flow

The password reset flow applies to local accounts in Azure AD B2C that use an email address or username with a password for sign-in.

Tip

The self-service password reset flow allows users to change their password when the user forgets their password and wants to reset it. Consider configuring a password change flow to support cases where a user knows their password and wants to change it.

A common practice after migrating users to Azure AD B2C with random passwords is to have the users verify their email addresses and reset their passwords during their first sign-in. It's also common to force the user to reset their password after an administrator changes their password; see force password reset to enable this feature.

Prerequisites

The new password reset experience is now part of the sign-up or sign-in policy. When the user selects the Forgot your password? link, they are immediately sent to the Forgot Password experience. Your application no longer needs to handle the AADB2C90118 error code, and you don't need a separate policy for password reset.

The self-service password reset experience can be configured for the Sign-in (Recommended) or Sign up and sign in (Recommended) user flows. If you don't have such a user flow, create a sign In and Sign Up user flow.

To enable self-service password reset for the sign-up or sign-in user flow:

  1. Sign in to the Azure portal.
  2. Select the Directory + Subscription icon in the portal toolbar, and then select the directory that contains your Azure AD B2C tenant.
  3. In the Azure portal, search for and select Azure AD B2C.
  4. Select User flows.
  5. Select a sign-up or sign-in user flow (of type Recommended) that you want to customize.
  6. Under Settings in the left menu, select Properties.
  7. Under Password complexity, select Self-service password reset.
  8. Select Save.
  9. Under Customize in the left menu, select Page layouts.
  10. In the Page Layout Version, choose 2.1.2 - Current or above.
  11. Select Save.

The following sections describe how to add a self-service password experience to a custom policy. The sample is based on the policy files included in the custom policy starter pack.

Tip

You can find a complete sample of the "sign-up or sign-in with password reset" policy on GitHub.

To indicate to the policy that the user has selected the Forgot your password? link, define a boolean claim. This claim will be used to direct the user journey to the Forgot Password technical profile. This claim can also be issued to the token so the application is aware that the user signed in via the Forgot Password flow.

You declare your claims in the claims schema. Open the extensions file of your policy. For example, SocialAndLocalAccounts/TrustFrameworkExtensions.xml.

  1. Search for the BuildingBlocks element. If the element doesn't exist, add it.
  2. Locate the ClaimsSchema element. If the element doesn't exist, add it.
  3. Add the following claim to the ClaimsSchema element.
<!-- 
<BuildingBlocks>
  <ClaimsSchema> -->
    <ClaimType Id="isForgotPassword">
      <DisplayName>isForgotPassword</DisplayName>
      <DataType>boolean</DataType>
      <AdminHelpText>Whether the user has selected Forgot your Password</AdminHelpText>
    </ClaimType>
  <!--
  </ClaimsSchema>
</BuildingBlocks> -->

Upgrade the page layout version

Page layout version 2.1.2 is required to enable the self-service password reset flow within the sign-up or sign-in journey.

  1. Search for the BuildingBlocks element. If the element doesn't exist, add it.
  2. Locate the ContentDefinitions element. If the element doesn't exist, add it.
  3. Modify the DataURI element within the ContentDefinition element with Id api.signuporsignin as shown below.
<!-- 
<BuildingBlocks>
  <ContentDefinitions> -->
    <ContentDefinition Id="api.signuporsignin">
      <DataUri>urn:com:microsoft:aad:b2c:elements:contract:unifiedssp:2.1.2</DataUri>
    </ContentDefinition>
  <!-- 
  </ContentDefinitions>
</BuildingBlocks> -->

To initiate the isForgotPassword claim, a claims transformation technical profile is used. This technical profile will be referenced later. When invoked, it will set the value of the isForgotPassword claim to true. Find the ClaimsProviders element. If the element doesn't exist, add it. Then add the following claims provider:

<!-- 
<ClaimsProviders> -->
  <ClaimsProvider>
    <DisplayName>Local Account</DisplayName>
    <TechnicalProfiles>
      <TechnicalProfile Id="ForgotPassword">
        <DisplayName>Forgot your password?</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="isForgotPassword" DefaultValue="true" AlwaysUseDefaultValue="true"/>
        </OutputClaims>
      </TechnicalProfile>
      <TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email">
        <Metadata>
          <Item Key="setting.forgotPasswordLinkOverride">ForgotPasswordExchange</Item>
        </Metadata>
      </TechnicalProfile>
    </TechnicalProfiles>
  </ClaimsProvider>
<!-- 
</ClaimsProviders> -->

The SelfAsserted-LocalAccountSignin-Email technical profile setting.forgotPasswordLinkOverride definers the password reset claims exchange to be executed in your user journey.

Add the password reset sub journey

Your journey will now include the capability for the user to sign in, sign up, and perform password reset. To better organize the user journey, a sub journey can be used to handle the password reset flow.

The sub journey will be called from the user journey and will perform the specific steps to deliver the password reset experience to the user. Use the Call type sub journey so that once the sub journey completes, control is returned to the orchestration step that initiated the sub journey.

Find the SubJourneys element. If the element doesn't exist, add it after the User Journeys element. Then add the following sub journey:

<!--
<SubJourneys>-->
  <SubJourney Id="PasswordReset" Type="Call">
    <OrchestrationSteps>
      <!-- Validate user's email address. -->
      <OrchestrationStep Order="1" Type="ClaimsExchange">
        <ClaimsExchanges>
          <ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" />
        </ClaimsExchanges>
      </OrchestrationStep>

      <!-- Collect and persist a new password. -->
      <OrchestrationStep Order="2" Type="ClaimsExchange">
        <ClaimsExchanges>
          <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
        </ClaimsExchanges>
      </OrchestrationStep>
    </OrchestrationSteps>
  </SubJourney>
<!--
</SubJourneys>-->

Prepare your user journey

You'll need to connect the Forgot your password? link to the Forgot Password sub journey. To do this, reference the Forgot Password sub journey Id within the ClaimsProviderSelection element of the CombinedSignInAndSignUp step.

If you don't have your own custom user journey with a CombinedSignInAndSignUp step, use the following procedure to duplicate an existing sign-up or sign-in user journey. Otherwise, continue to the next section.

  1. Open the TrustFrameworkBase.xml file from the starter pack.
  2. Find and copy the entire contents of the UserJourney element that includes Id="SignUpOrSignIn".
  3. Open the TrustFrameworkExtensions.xml and find the UserJourneys element. If the element doesn't exist, add one.
  4. Create a child element of the UserJourneys element by pasting the entire contents of the UserJourney element you copied in step 2.
  5. Rename the Id of the user journey. For example, Id="CustomSignUpSignIn".

In your user journey, you can represent the Forgot Password sub journey as a ClaimsProviderSelection. Adding this element connects the Forgot your password? link to the Forgot Password sub journey.

  1. In the user journey, find the orchestration step element that includes Type="CombinedSignInAndSignUp" or Type="ClaimsProviderSelection". It's usually the first orchestration step. The ClaimsProviderSelections element contains a list of identity providers that a user can use to sign in. Add the following line:

    <ClaimsProviderSelection TargetClaimsExchangeId="ForgotPasswordExchange" />
    
  2. In the next orchestration step, add a ClaimsExchange element. Add the following line:

    <ClaimsExchange Id="ForgotPasswordExchange" TechnicalProfileReferenceId="ForgotPassword" />
    
  3. Add the following orchestration step between the current step, and the next step. The new orchestration step you add, checks whether the isForgotPassword claim exists. If the claim exists, it invokes the password reset sub journey.

    <OrchestrationStep Order="3" Type="InvokeSubJourney">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="false">
          <Value>isForgotPassword</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <JourneyList>
        <Candidate SubJourneyReferenceId="PasswordReset" />
      </JourneyList>
    </OrchestrationStep>
    
  4. After you add the new orchestration step, renumber the steps sequentially without skipping any integers from 1 to N.

Set the user journey to be executed

Now that you've modified or created a user journey, in the Relying Party section specify the journey that Azure AD B2C will execute for this custom policy. Within the RelyingParty element, find the DefaultUserJourney element. Update the DefaultUserJourney ReferenceId to match the ID of the user journey in which you added the ClaimsProviderSelections.

<RelyingParty>
  <DefaultUserJourney ReferenceId="CustomSignUpSignIn" />
  ...
</RelyingParty>

Indicate the Forgot Password flow to your App

Your application might need to detect whether the user signed in via the Forgot Password user flow. The isForgotPassword claim contains a boolean value that indicates this, which can be issued in the token sent to your application. If necessary, add isForgotPassword to the output claims in the Relying Party section. Your application can check the isForgotPassword claim to determine if the user resets their password.

<RelyingParty>
  <OutputClaims>
    ...
    <OutputClaim ClaimTypeReferenceId="isForgotPassword" DefaultValue="false" />
  </OutputClaims>
</RelyingParty>

Upload the custom policy

  1. Sign in to the Azure portal.
  2. Select the Directory + Subscription icon in the portal toolbar, and then select the directory that contains your Azure AD B2C tenant.
  3. In the Azure portal, search for and select Azure AD B2C.
  4. Under Policies, select Identity Experience Framework.
  5. Select Upload Custom Policy, and then upload the two policy files that you changed in the following order:
    1. The extension policy, for example TrustFrameworkExtensions.xml.
    2. The relying party policy, for example SignUpSignIn.xml.

Test the password reset flow

  1. Select a sign-up or sign-in user flow (of type Recommended) that you want to test.
  2. Select Run user flow.
  3. For Application, select the web application named webapp1 that you previously registered. The Reply URL should show https://jwt.ms.
  4. Select Run user flow.
  5. From the sign-up or sign-in page, select Forgot your password?.
  6. Verify the email address of the account that you previously created, and then select Continue.
  7. You now have the opportunity to change the password for the user. Change the password and select Continue. The token is returned to https://jwt.ms and should be displayed to you.
  8. Check the return token's isForgotPassword claim value. If exists and is set to true, this indicates the user has reset the password.

Password reset policy (legacy)

If the self-service password reset experience is not enabled, clicking this link doesn't automatically trigger a password reset user flow. Instead, the error code AADB2C90118 is returned to your application. Your application needs to handle this error code by reinitializing the authentication library to authenticate an Azure AD B2C password reset user flow.

In the following diagram:

  1. From the application, the user clicks on sign-in. The app initiates an authorization request, and takes the user to Azure AD B2C to finish signing in. The authorization request specifies the sign-up or sign-in policy name, such as B2C_1_signup_signin.
  2. The user selects the Forgot your password? link. Azure AD B2C returns the AADB2C90118 error code to the application.
  3. The application handles the error code and initiates a new authorization request. The authorization request specifies the password reset policy name, such as B2C_1_pwd_reset.

Legacy password reset user flow

To see an example, take a look at a simple ASP.NET sample, which demonstrates the linking of user flows.

Create a password reset user flow

To let users of your application reset their password, you create a password reset user flow.

  1. In the Azure AD B2C tenant overview menu, select User flows, and then select New user flow.
  2. On the Create a user flow page, select the Password reset user flow.
  3. Under Select a version, select Recommended, and then select Create.
  4. Enter a Name for the user flow. For example, passwordreset1.
  5. For Identity providers, enable Reset password using email address.
  6. Under Application claims, select Show more and choose the claims you want returned in the authorization tokens sent back to your application. For example, select User's Object ID.
  7. Select OK.
  8. Select Create to add the user flow. A prefix of B2C_1 is automatically appended to the name.

Test the user flow

  1. Select the user flow you created to open its overview page, and then select Run user flow.
  2. For Application, select the web application named webapp1 that you previously registered. The Reply URL should show https://jwt.ms.
  3. Click Run user flow, verify the email address of the account that you previously created, and then select Continue.
  4. You can now change the password for the user. Change the password and select Continue. The token is returned to https://jwt.ms and should be displayed to you.

Create a password reset policy

Custom policies are a set of XML files you upload to your Azure AD B2C tenant to define user journeys. We provide starter packs with several pre-built policies including: sign-up and sign-in, password reset, and profile editing policy. For more information, see Get started with custom policies in Azure AD B2C.

Next steps

Set up a force password reset.