Azure B2C自定义策略:密码重置页面重复出现问题求助
Azure AD B2C自定义策略忘记密码流程重复要求输入新密码问题
我在自定义统一登录/注册页面(自定义策略)上配置了忘记密码功能,功能可正常运行,但用户需要在两个页面输入新密码(及确认密码)而非一个。流程如下:
- 用户点击“忘记密码”
- 流程要求用户输入邮箱地址
- 输入邮箱并验证验证码后,进入要求输入新密码(及确认)的页面
- 点击继续后,再次进入要求输入新密码(及确认)的页面
- 无论如何,用户输入新密码并继续后,密码成功修改

用户本应只被要求输入一次新密码(及确认),请问我哪里配置出错了?
我遵循了官方的自定义策略添加密码重置指导文档。
更新:以下是策略中的UserJourney和SubJourneys元素,其余内容涉及敏感信息无法提供
<TrustFrameworkPolicy> <UserJourneys> <UserJourney Id="CustomSignUpSignIn"> <OrchestrationSteps> <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin"> <ClaimsProviderSelections> <ClaimsProviderSelection TargetClaimsExchangeId="PasswordResetUsingEmailAddressExchange" /> <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" /> <ClaimsProviderSelection TargetClaimsExchangeId="ForgotPasswordExchange" /> </ClaimsProviderSelections> <ClaimsExchanges> <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="2" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimsExist" ExecuteActionsIf="true"> <Value>objectId</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="ForgotPasswordExchange" TechnicalProfileReferenceId="ForgotPassword" /> <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" /> <ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="3" Type="InvokeSubJourney"> <Preconditions> <Precondition Type="ClaimsExist" ExecuteActionsIf="false"> <Value>isForgotPassword</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <JourneyList> <Candidate SubJourneyReferenceId="PasswordReset" /> </JourneyList> </OrchestrationStep> <OrchestrationStep Order="4" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimsExist" ExecuteActionsIf="false"> <Value>isPasswordResetFlow</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="5" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimsExist" ExecuteActionsIf="true"> <Value>objectId</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="SelfAsserted-Social" TechnicalProfileReferenceId="SelfAsserted-Social" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="6" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="7" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimsExist" ExecuteActionsIf="true"> <Value>isActiveMFASession</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="PhoneFactor-Verify" TechnicalProfileReferenceId="PhoneFactor-InputOrVerify" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="8" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimsExist" ExecuteActionsIf="false"> <Value>newPhoneNumberEntered</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="AADUserWriteWithObjectId" TechnicalProfileReferenceId="AAD-UserWritePhoneNumberUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="9" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" /> </OrchestrationSteps> <ClientDefinition ReferenceId="DefaultWeb" /> </UserJourney> <UserJourney Id="UserInfoJourney" DefaultCpimIssuerTechnicalProfileReferenceId="UserInfoIssuer"> <Authorization> <AuthorizationTechnicalProfiles> <AuthorizationTechnicalProfile ReferenceId="UserInfoAuthorization" /> </AuthorizationTechnicalProfiles> </Authorization> <OrchestrationSteps> <OrchestrationStep Order="1" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimsExist" ExecuteActionsIf="false"> <Value>objectId</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges UserIdentity="false"> <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="2" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="UserInfoIssuer" /> </OrchestrationSteps> </UserJourney> </UserJourneys> <SubJourneys> <SubJourney Id="PasswordReset" Type="Call"> <OrchestrationSteps> <!-- Validate user's email address. --> <OrchestrationStep Order="1" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" /> </ClaimsExchanges> </OrchestrationStep> <!-- Collect and persist a new password. --> <OrchestrationStep Order="2" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep> </OrchestrationSteps> </SubJourney> </SubJourneys> </TrustFrameworkPolicy>
问题原因
你的策略中存在两次触发密码收集写入的逻辑:
- 在
PasswordReset子旅程的第2步,已经调用LocalAccountWritePasswordUsingObjectId完成了新密码的收集和写入操作。 - 主用户旅程的第4步,又通过
isPasswordResetFlow声明判断,再次调用了同一个技术配置文件,导致用户被重复要求输入密码。
解决方案
直接删除主用户旅程中Order="4"的OrchestrationStep即可,因为密码重置子旅程已经完成了密码写入的全部操作,无需重复执行。
如果该步骤需要保留用于其他业务场景,可以修改前置条件,确保忘记密码流程跳过这一步:
<OrchestrationStep Order="4" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimsExist" ExecuteActionsIf="false"> <Value>isPasswordResetFlow</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> <Precondition Type="ClaimsExist" ExecuteActionsIf="true"> <Value>isForgotPassword</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep>
核心是确保忘记密码流程中只执行一次密码收集和写入操作,避免重复触发页面。
内容的提问来源于stack exchange,提问作者codeshinobi
相关产品推荐
相关产品推荐

