B2C password reset custom policy with REST API call issue

Vikas Tiwari 766 Reputation points
2021-02-04T06:42:16.38+00:00

Hi @AmanpreetSingh-MSFT ,

I am using password reset custom policy which calls REST API to execute some additional password complexity, when I try to change password it gets stuck with message "Please wait while we process your information." (img attached).

Following are my policy details (I took reference from here):

   <ClaimType Id="oldPassword">  
   <DisplayName>Old Password</DisplayName>  
   <DataType>string</DataType>  
   <UserHelpText>Enter your old password</UserHelpText>  
   <UserInputType>Password</UserInputType>  
      </ClaimType>  
   <ClaimType Id="newPassword">  
   <PredicateValidationReference Id="CustomPassword" />  
   </ClaimType>  
   <ClaimType Id="reenterPassword">  
   <PredicateValidationReference Id="CustomPassword" />  
   </ClaimType>  
   <ClaimType Id="isPasswordHistoryValid">  
        <DisplayName>isPasswordHistoryValid</DisplayName>  
        <DataType>boolean</DataType>  
        <AdminHelpText>isPasswordHistoryValid</AdminHelpText>  
        <UserHelpText>isPasswordHistoryValid</UserHelpText>  
      </ClaimType>  
   <ClaimType Id="userMessage">  
        <DataType>string</DataType>  
        <UserHelpText>Add help text here</UserHelpText>  
        <UserInputType>Paragraph</UserInputType>  
      </ClaimType>  
  
 <ClaimsProvider>  
 <DisplayName>Local Account SignIn</DisplayName>  
 <TechnicalProfiles>  
        <TechnicalProfile Id="login-NonInteractive-PasswordChange">  
          <DisplayName>Local Account SignIn</DisplayName>  
          <InputClaims>  
            <InputClaim ClaimTypeReferenceId="oldPassword" PartnerClaimType="password" Required="true" />  
          </InputClaims>  
          <IncludeTechnicalProfile ReferenceId="login-NonInteractive" />  
        </TechnicalProfile>  
      </TechnicalProfiles>  
    </ClaimsProvider>  
 <ClaimsProvider>  
    <DisplayName>Local Account Password Change</DisplayName>  
    <TechnicalProfiles>  
      <TechnicalProfile Id="LocalAccountWritePasswordChangeUsingObjectId">  
        <DisplayName>Change password (username)</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.localaccountpasswordreset</Item>  
        </Metadata>  
        <InputClaims>  
          <InputClaim ClaimTypeReferenceId="objectId" />  
        </InputClaims>  
        <OutputClaims>  
          <OutputClaim ClaimTypeReferenceId="oldPassword" Required="true" />  
          <OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />  
          <OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />  
        </OutputClaims>  
        <ValidationTechnicalProfiles>  
          <ValidationTechnicalProfile ReferenceId="login-NonInteractive-PasswordChange" />  
   <ValidationTechnicalProfile ReferenceId="REST-PasswordHistory" ContinueOnError="false">  
 <Preconditions>  
                <Precondition Type="ClaimsExist" ExecuteActionsIf="true">  
                  <Value>isPasswordHistoryValid</Value>  
                  <Value>False</Value>  
                  <Action>SkipThisValidationTechnicalProfile</Action>  
                </Precondition>  
             </Preconditions>  
          </ValidationTechnicalProfile>  
          <ValidationTechnicalProfile ReferenceId="AAD-UserWritePasswordUsingObjectId" ContinueOnError="false" />  
        </ValidationTechnicalProfiles>  
      </TechnicalProfile>  
    </TechnicalProfiles>  
  </ClaimsProvider>  
 <ClaimsProvider>  
      <DisplayName>Custom REST API</DisplayName>  
      <TechnicalProfiles>  
    <TechnicalProfile Id="REST-PasswordHistory">  
          <DisplayName>Validate password history via custom API</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://apiendpoint</Item>  
            <Item Key="SendClaimsIn">Body</Item>  
            <Item Key="AllowInsecureAuthInProduction">false</Item>  
          </Metadata>  
          <InputClaims>  
            <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="userId" />  
            <InputClaim ClaimTypeReferenceId="newPassword" PartnerClaimType="Password" />  
 <InputClaim ClaimTypeReferenceId="oldPassword" PartnerClaimType="oldPassword" />  
          </InputClaims>  
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />  
        </TechnicalProfile>  
   </TechnicalProfiles>  
    </ClaimsProvider>  
 <ClaimsProvider>  
      <DisplayName>Self-Asserted</DisplayName>  
      <TechnicalProfiles>  
        <TechnicalProfile Id="SelfAsserted-PasswordResetError">  
          <DisplayName>Password reset error message</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.selfasserted</Item>  
          </Metadata>  
          <InputClaimsTransformations>  
            <InputClaimsTransformation ReferenceId="PasswordResetErrorMessage" />  
          </InputClaimsTransformations>  
          <InputClaims>  
            <InputClaim ClaimTypeReferenceId="isPasswordHistoryValid" />  
            <InputClaim ClaimTypeReferenceId="userMessage" />  
          </InputClaims>  
          <OutputClaims>  
            <OutputClaim ClaimTypeReferenceId="isPasswordHistoryValid" />  
            <OutputClaim ClaimTypeReferenceId="userMessage" />  
          </OutputClaims>  
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />  
        </TechnicalProfile>  
      </TechnicalProfiles>  
    </ClaimsProvider>  
  
 <UserJourneys>  
 <UserJourney Id="PasswordChange">  
    <OrchestrationSteps>  
       <OrchestrationStep Order="1" Type="ClaimsProviderSelection" ContentDefinitionReferenceId="api.signuporsignin">  
          <ClaimsProviderSelections>  
            <ClaimsProviderSelection TargetClaimsExchangeId="LocalAccountSigninEmailExchange" />  
          </ClaimsProviderSelections>  
        </OrchestrationStep>  
        <OrchestrationStep Order="2" Type="ClaimsExchange">  
          <ClaimsExchanges>  
            <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />  
          </ClaimsExchanges>  
        </OrchestrationStep>  
        <OrchestrationStep Order="3" Type="ClaimsExchange">  
          <ClaimsExchanges>  
            <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordChangeUsingObjectId" />  
          </ClaimsExchanges>  
        </OrchestrationStep>  
 <OrchestrationStep Order="4" Type="ClaimsExchange">  
          <ClaimsExchanges>  
            <ClaimsExchange Id="SelfAsserted-PasswordResetError" TechnicalProfileReferenceId="SelfAsserted-PasswordResetError" />  
          </ClaimsExchanges>  
        </OrchestrationStep>  
        <OrchestrationStep Order="5" Type="ClaimsExchange">  
          <ClaimsExchanges>  
            <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />  
          </ClaimsExchanges>  
        </OrchestrationStep>  
        <OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />  
    </OrchestrationSteps>  
    <ClientDefinition ReferenceId="DefaultWeb" />  
   </UserJourney>  
  </UserJourneys>  

Also, if I try to comment REST api call then change password button redirects to 500 error.

Could you review and help me to find the root cause here?

Thanks,
Vikas Tiwari

Microsoft Entra External ID
Microsoft Entra External ID
A modern identity solution for securing access to customer, citizen and partner-facing apps and services. It is the converged platform of Azure AD External Identities B2B and B2C. Replaces Azure Active Directory External Identities.
2,775 questions
{count} vote

1 answer

Sort by: Most helpful
  1. Vikas Tiwari 766 Reputation points
    2021-02-05T06:13:02.347+00:00

    Hi @AmanpreetSingh-MSFT , I have found the issue your github repo is all correct I missed AuthenticationType while calling API, now its able to send request to API.

    Though for invalid password scenario (when my API return invalid new password response) It doesn't show error message on screen, below are my technical profile and user journey:

    <ClaimsProvider>  
        <DisplayName>Local Account Password Change</DisplayName>  
        <TechnicalProfiles>  
          <TechnicalProfile Id="LocalAccountWritePasswordChangeUsingObjectId">  
            <DisplayName>Change password (username)</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.localaccountpasswordreset</Item>  
            </Metadata>  
            <InputClaims>  
              <InputClaim ClaimTypeReferenceId="objectId" />  
            </InputClaims>  
            <OutputClaims>  
              <OutputClaim ClaimTypeReferenceId="oldPassword" Required="true" />  
              <OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />  
              <OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />  
            </OutputClaims>  
            <ValidationTechnicalProfiles>  
    		<ValidationTechnicalProfile ReferenceId="login-NonInteractive-PasswordChange" />  
    		  <ValidationTechnicalProfile ReferenceId="REST-PasswordHistory" ContinueOnError="false" />  
              <ValidationTechnicalProfile ReferenceId="AAD-UserWritePasswordUsingObjectId" ContinueOnError="false">  
    			<Preconditions>  
                    <Precondition Type="ClaimEquals" ExecuteActionsIf="true">  
                      <Value>isPasswordHistoryValid</Value>  
                      <Value>False</Value>  
                      <Action>SkipThisValidationTechnicalProfile</Action>  
                    </Precondition>  
                 </Preconditions>  
              </ValidationTechnicalProfile>  
            </ValidationTechnicalProfiles>  
          </TechnicalProfile>  
        </TechnicalProfiles>  
      </ClaimsProvider>  
    <ClaimsProvider>  
          <DisplayName>Custom REST API</DisplayName>  
          <TechnicalProfiles>  
    	   <TechnicalProfile Id="REST-PasswordHistory">  
              <DisplayName>Validate password history via custom API</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://apiendpoint.com</Item>  
                <Item Key="SendClaimsIn">Body</Item>  
    	    <Item Key="AuthenticationType">None</Item>  
                <Item Key="AllowInsecureAuthInProduction">true</Item>  
              </Metadata>  
              <InputClaims>  
                <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="userId" />  
                <InputClaim ClaimTypeReferenceId="newPassword" PartnerClaimType="Password" />  
    	    <InputClaim ClaimTypeReferenceId="oldPassword" PartnerClaimType="oldPassword" />  
              </InputClaims>    
              <OutputClaims>  
                <OutputClaim ClaimTypeReferenceId="isPasswordHistoryValid" DefaultValue="false" />  
              </OutputClaims>  
              <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />  
            </TechnicalProfile>  
    	  </TechnicalProfiles>  
        </ClaimsProvider>  
       <UserJourney Id="PasswordChange">  
        <OrchestrationSteps>  
           <OrchestrationStep Order="1" Type="ClaimsProviderSelection" ContentDefinitionReferenceId="api.signuporsignin">  
              <ClaimsProviderSelections>  
                <ClaimsProviderSelection TargetClaimsExchangeId="LocalAccountSigninEmailExchange" />  
              </ClaimsProviderSelections>  
            </OrchestrationStep>  
            <OrchestrationStep Order="2" Type="ClaimsExchange">  
              <ClaimsExchanges>  
                <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />  
              </ClaimsExchanges>  
            </OrchestrationStep>  
            <OrchestrationStep Order="3" Type="ClaimsExchange">  
              <ClaimsExchanges>  
                <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordChangeUsingObjectId" />  
              </ClaimsExchanges>  
            </OrchestrationStep>  
    		<OrchestrationStep Order="4" Type="ClaimsExchange">  
              <Preconditions>  
                <Precondition Type="ClaimEquals" ExecuteActionsIf="true">  
                  <Value>isPasswordHistoryValid</Value>  
                  <Value>True</Value>  
                  <Action>SkipThisOrchestrationStep</Action>  
                </Precondition>  
              </Preconditions>  
              <ClaimsExchanges>  
                <ClaimsExchange Id="SelfAsserted-PasswordResetError" TechnicalProfileReferenceId="SelfAsserted-PasswordResetError" />  
              </ClaimsExchanges>  
            </OrchestrationStep>  
            <OrchestrationStep Order="5" Type="ClaimsExchange">  
              <ClaimsExchanges>  
                <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />  
              </ClaimsExchanges>  
            </OrchestrationStep>  
            <OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />  
        </OrchestrationSteps>  
        <ClientDefinition ReferenceId="DefaultWeb" />  
       </UserJourney>  
    
    1 person found this answer helpful.