samples
samples copied to clipboard
Add forgot password link in Dynamic Sigin/Signup sample
I'm trying to use the https://github.com/azure-ad-b2c/samples/tree/master/policies/dynamic-sign-up-sign-in sample, however I need to add a forgot password link on step 2 (reminder: step 1 asks the user for their email, and checks if a user exists, if it does, step 2 asks the user for their password).
Step 1:
Step 2:
What's missing:
I'm hoping someone else has run into the same problem, as surely nobody is rolling out login flows that don't allow you to reset your password :)
I've got self-service password reset working in other flows, however applying that to this flow hasn't worked (the flow works, but the forgot password link isn't shown).
The problem here I think is that there needs to be a ClaimsProviderSelection OrchestrationStep once the user gets to step 2, but i'm not sure how to do that, and the B2C custom policy docs are... confusing.
I noted a solution was provided in https://github.com/azure-ad-b2c/samples/issues/390, but that solution doesn't work, I think that's because they used a different sample, which doesn't have multiple steps like the dynamic signin/signup one does.
Any help would be greatly appreciated!
Here's my user journey. It's pretty much the same as the sample linked above, just with the forgot password stuff as per the docs (also above). The technical profiles and relying party is the same as the sample.
<UserJourney Id="DynamicSignUpOrSignIn">
<OrchestrationSteps>
<OrchestrationStep Order="1" Type="ClaimsExchange"
ContentDefinitionReferenceId="api.signuporsignin">
<ClaimsExchanges>
<ClaimsExchange Id="LocalAccountSigninEmailExchange"
TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Dynamic" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- Run this step when a user select the "Sign-up now" link -->
<OrchestrationStep Order="2" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>objectId</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>readOnlyEmail</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="SignUpWithLogonEmailExchange"
TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- Run this step when a user tries to sign-in with unregistered account -->
<OrchestrationStep Order="3" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>objectId</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
<Precondition Type="ClaimsExist" ExecuteActionsIf="false">
<Value>readOnlyEmail</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="DynamicSignUp"
TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail_Implicit" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- If objectId was returned in step 2, then this must be a sign in -->
<OrchestrationStep Order="4" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>newUser</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="SignInPasswordPage"
TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Password" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="5" Type="InvokeSubJourney">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="false">
<Value>isForgotPassword</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<JourneyList>
<Candidate SubJourneyReferenceId="PasswordReset" />
</JourneyList>
</OrchestrationStep>
<!-- This step reads any user attributes that we may not have received when authenticating
using ESTS so they can be sent
in the token. -->
<OrchestrationStep Order="6" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimEquals" ExecuteActionsIf="true">
<Value>authenticationSource</Value>
<Value>socialIdpAuthentication</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadWithObjectId"
TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- The previous step (SelfAsserted-Social) could have been skipped if there were no
attributes to collect
from the user. So, in that case, create the user in the directory if one does not already exist
(verified using objectId which would be set from the last step if account was created in the
directory. -->
<OrchestrationStep Order="7" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>objectId</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="AADUserWrite"
TechnicalProfileReferenceId="AAD-UserWriteUsingLogonEmail" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="8" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
</OrchestrationSteps>
</UserJourney>
You would have to make the 2nd screen (password collection), a Combined Sign In and Sign Up page, rather than a SelfAsserted page.
can you please provide a sample policy for that @JasSuri
I am also having similar issue as @sh-jthorpe
Hi @sh-jthorpe did you seem to find a solution?
I am also facing similar issue, I also made 2nd screen (password collection), a Combined Sign In and Sign Up page, but seems to cause problems @JasSuri
Hi @sh-jthorpe did you seem to find a solution?
I am also facing similar issue, I also made 2nd screen (password collection), a Combined Sign In and Sign Up page, but seems to cause problems @JasSuri
Hi, no I haven't. When I have time I'll probably go through paid azure support.
For now we're making do with a more standard custom policy, even though it's a worse experience.
I seem to have figured out the solution here -- Basic idea is instead of showing password page I am triggering basic sign in screen and made it as Combined sign in and sign up and also used content definition as 'api.signuporsignin'
Main thing to change here is we need to use a base technical profile - 'SelfAsserted-LocalAccountSignin-Email' instead of 'SelfAsserted-LocalAccountSignin-Password' in step 4 - so step 4 will look like as below
<OrchestrationStep Order="4" Type="CombinedSignInAndSignUp"
ContentDefinitionReferenceId="api.signuporsignin">
<!-- skip this step if sign up flow was executed via step 2 or 3 -->
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>executed-SelfAsserted-Input</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsProviderSelections>
<ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange2" />
<ClaimsProviderSelection TargetClaimsExchangeId="ForgotPasswordExchange" />
</ClaimsProviderSelections>
<ClaimsExchanges>
<ClaimsExchange Id="LocalAccountSigninEmailExchange2"
TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
</ClaimsExchanges>
</OrchestrationStep>
This will make the forgot password link appear. To link this link to actual password reset journey and get rid of Error - AADB2C90118 - we can refer to this documentation - https://learn.microsoft.com/en-us/azure/active-directory-b2c/add-password-reset-policy?pivots=b2c-custom-policy
I followed this and it worked! Hope this helps.