azure-ad-b2cazure-ad-b2c-custom-policyforgot-password

Email Address Verification, in SubJourney with additional ValidationTechnicalProfile


We are trying to do Just In Time migration with the 'SubJourney' based password reset (e.g. forgot your password).

I need to be able to migrate the user prior to resetting their password via a REST call. However, when I add the entry for our ValidationTechnicalProfile REST call

<ValidationTechnicalProfile ReferenceId="REST-UserMigration-LocalAccount-LoalAccountUserExsist"/>

the UI changes. The email verification steps (enter email, verify code) just disappear, leaving me with enter password boxes.

It goes from this:

Correct Email Verification

To this:

Just password change boxes

The only change is the addition of the ValidationTechnicalProfile Entry

<TechnicalProfile Id="LocalAccountDiscoveryUsingEmailAddress-Migration">
  <DisplayName>Reset password using email address</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.localaccountpasswordreset</Item>                       
  </Metadata>
  <CryptographicKeys>
    <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
  </CryptographicKeys>
  <IncludeInSso>false</IncludeInSso>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />                   
    <OutputClaim ClaimTypeReferenceId="objectId" />
    <OutputClaim ClaimTypeReferenceId="userPrincipalName" />
    <OutputClaim ClaimTypeReferenceId="authenticationSource" />            
  </OutputClaims>
  <ValidationTechnicalProfiles> 
     <!--- Adding and removing this line --->
    <ValidationTechnicalProfile ReferenceId="REST-UserMigration-LocalAccount-LoalAccountUserExsist"/>        

    <ValidationTechnicalProfile ReferenceId="AAD-UserReadUsingEmailAddress"/>    

  </ValidationTechnicalProfiles>
  
</TechnicalProfile>               
<TechnicalProfile Id="REST-UserMigration-LocalAccount-LoalAccountUserExsist">
    <DisplayName>Migrate user password flow</DisplayName>
    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    <Metadata>
    <Item Key="ServiceUrl">https://somefunctapp-rest-api.azurewebsites.net/api/MigrateIfExists?code=ugqr4ESgMENWlRdILvuOWkksuLy-zoPm76stOuiHFtzFAzzuiHFKcw==</Item>
    <Item Key="AuthenticationType">None</Item>
    <Item Key="SendClaimsIn">Body</Item>
    <Item Key="AllowInsecureAuthInProduction">True</Item>
    </Metadata>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="signInName" />
    <InputClaim ClaimTypeReferenceId="password" />
  </InputClaims>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="migrationRequired" />
    <OutputClaim ClaimTypeReferenceId="email" />
    <OutputClaim ClaimTypeReferenceId="newPassword" />
    <OutputClaim ClaimTypeReferenceId="displayName" />
    <OutputClaim ClaimTypeReferenceId="givenName" />
    <OutputClaim ClaimTypeReferenceId="surName" />
    <OutputClaim ClaimTypeReferenceId="sub" PartnerClaimType="userId" />
    <OutputClaim ClaimTypeReferenceId="trueValue" DefaultValue="true"/>
  </OutputClaims>
  <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>  
<SubJourney Id="PasswordReset-Mine" Type="Call">
  <OrchestrationSteps>
    <!-- Validate user's email address. Run this step only when user resets the password-->
    <OrchestrationStep Order="1" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress-Migration" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- Collect and persist a new password. Run this step only when user resets the password-->
    <OrchestrationStep Order="2" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>
  </OrchestrationSteps>
</SubJourney>

What am I doing wrong? Happy to provide any additional information or screen shots.


Solution

  • Display claims mitigates these strange 'disappearing' behaviors. Output claims can have unexpected behaviors when the value exists in the claim bag. My recommendation is converting your output claims to display claims and see if this fixes the behavior before continuing investing the issue.