I'm trying to implement a password change custom policy for Azure AD B2C.
I've used this file as a base, changed the tenantid, and uploaded it to Azure.
When I try a demo from the Azure portal, it asks me to log in, then asks for an old password and a new password to change it. And it works perfectly fine. I can change my password there.
Then I've implemented a button, that redirects to the password change URL.
private redirectPasswordChange(appConfigService: AppConfigService): void {
const passwordChangeUrl = `${appConfigService.config.AD_AUTHORITY_CHANGE}?client_id=${appConfigService.config.AD_CLIENT_ID}
&nonce=defaultNonce
&redirect_uri=${appConfigService.config.BASE_URL}
&scope=openid
&response_type=id_token`;
if (isPlatformBrowser(PLATFORM_ID)) {
window.location.href = passwordChangeUrl;
} else {
this.window.location.href = passwordChangeUrl;
}
}
I've removed prompt=login from the URL because the button that is going to redirect to the password change URL is on the "My profile" section on our website. So users are already logged in, and I don't want them to log in again.
Then I tested it on our website, when I click to button, it redirects me to the password change page, it asks for my old password, new password, and confirmation of it, which is perfect for me. But the problem is, it doesn't accept my old password, it says "The username or password provided in the request are invalid".
I've searched for the problem online, including StackOverflow, but I found that there are lots of different answers for this problem. One of them is saying that:
Its because these input claims are overwriting the input claim names for login-noninteractive.
<InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="client_credentials" />
<InputClaim ClaimTypeReferenceId="scope" DefaultValue="https://{{tenantID}}.onmicrosoft.com/{{registeredApiAppName}}/.default" />
</InputClaims>
use different claim names, and use a partnerclaimtype to send the value with the original claim name.
https://stackoverflow.com/a/65931145/8831824
When I take a look, I can see that those orchestrationsteps on PasswordChange.xml are the same in TrustFrameworkBase.xml
<OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin"> <ClaimsProviderSelections> <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" /> </ClaimsProviderSelections> <ClaimsExchanges> <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" /> </ClaimsExchanges> </OrchestrationStep>
<OrchestrationStep Order="3" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep>
Is there some kind of overwriting here? I mean, they are exactly the same, but in two different files, In TrustFrameworkBase.xml, for SignUpOrSignIn journey, and PasswordChange.xml, for PasswordChange journey.
Here are the policies I have. I did put great effort to solve the problem, but I couldn't even identify it. Hope someone can give me an idea to work on it. Thanks for reading.
TrustFrameworkBase.xml: https://pastebin.com/RXXhcwpN
TrustFrameworkExtensions.xml: https://pastebin.com/UUfVNaJ7
PasswordChange.xml : https://pastebin.com/sPjZjNYT
PasswordReset.xml : https://pastebin.com/CxE3pMH3
