B2C password reset custom policy with REST API call issue

Vikas Tiwari 771 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 Security Microsoft Entra Microsoft Entra External ID
{count} vote

1 answer

Sort by: Most helpful
  1. Vikas Tiwari 771 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.

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.