B2C 重置密码流程在 Microsoft 文档中不起作用

B2C Reset Password Flow not working from Microsoft docs

https://docs.microsoft.com/en-us/azure/active-directory-b2c/add-password-reset-policy?pivots=b2c-custom-policy

我正在按照 Microsoft 为自定义策略模板和启动包提供的配置示例进行操作(请注意,启动包仍然包含 API 版本 1.0.0 页面布局的所有模板)。 已将流程更新为模板 2.1.4(最新稳定版)以及 1.2.1 或 Microsoft 在此页面上推荐的其他版本: https://docs.microsoft.com/en-us/azure/active-directory-b2c/contentdefinitions#migrating-to-page-layout.

但是,每次我在上传我的 3 个自定义策略(基础、扩展、注册登录)后单击忘记密码 link 时,我都会在我的 appInsights 实例中收到以下错误:

在租户“yourTenant.onmicrosoft.com”的 ID 为“AAD-UserReadUsingAlternativeSecurityId-NoError”策略“B2C_1A_signup_signin”的技术配置文件中定义的 ID 为“alternativeSecurityId”的查找声明找不到声明。

注意:我在这里输入了“yourtenant”,但显然不是我的租户名称。 登录流程以及我对政策所做的任何其他自定义工作正常。 我什至回过头来将策略设置为没有任何自定义,只是尝试设置密码重置流程,但仍然没有运行示例。

不幸的是,没有太多信息可以帮助我解决这个错误,所以想向社区寻求一些指导,或者如果有人有重置策略的这一部分的工作示例,如果没有只是考虑创建一个标准的 userJourney推荐版本重置密码明显不行

好的,经过 2 天的反复试验,我终于让它工作了。所以说明书上少了一个步骤。在忘记密码的索赔交换之后,但在调用子旅程之前,您实际上必须调用索赔交换。话虽如此,我是这样做的:

<!--This step will trigger the actual forgot password exchange and show us the page from the integrated policy.-->
    <OrchestrationStep Order="4" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>objectId</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="ForgotPasswordXchange" TechnicalProfileReferenceId="ForgotPassword" /> 
      </ClaimsExchanges><!--Id must be unique-->
    </OrchestrationStep>

万一有人想要更正某些内容或发送更新或建议,这就是我的用户旅程最终的样子,我的子旅程:

<UserJourneys>
    <UserJourney Id="CustomSignUpOrSignIn">
      <OrchestrationSteps>
        <!-- HRD initialization -->
        <!-- Changes based off of  <UserJourney Id="HRD_Internal">  -->
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="HRD" TechnicalProfileReferenceId="HRD_Function" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
          <Preconditions>
            <!--
           <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
             <Value>idp</Value>
             <Action>SkipThisOrchestrationStep</Action>
           </Precondition>
           -->
            <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
              <Value>idpHint</Value>
              <Value></Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsProviderSelections>
            <ClaimsProviderSelection TargetClaimsExchangeId="TestExchange1" />
            <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
            <ClaimsProviderSelection TargetClaimsExchangeId="ForgotPasswordExchange" />
          </ClaimsProviderSelections>
          <ClaimsExchanges>
            <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- Check if the user has selected to sign in using one of the social providers -->
        <OrchestrationStep Order="3" Type="ClaimsExchange">
          <Preconditions>
            <!--
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>idp</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
            -->
            <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
              <Value>idpHint</Value>
              <Value></Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="TestExchange1" TechnicalProfileReferenceId="ConcentrixAD-OpenIdConnect" />
            <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
            <ClaimsExchange Id="ForgotPasswordExchange" TechnicalProfileReferenceId="ForgotPassword" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!--This step will trigger the actual forgot password exchange and show us the page from the integrated policy.-->
        <OrchestrationStep Order="4" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="ForgotPasswordExchange" TechnicalProfileReferenceId="ForgotPassword" />
          </ClaimsExchanges> <!--Id must be unique-->
        </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>
        <OrchestrationStep Order="6" Type="ClaimsExchange" ContentDefinitionReferenceId="api.signuporsignin">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
              <Value>idpHint</Value>
              <Value>okta</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="HintedOktaSAMLExchange" TechnicalProfileReferenceId="Okta-SAML2" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- For social IDP authentication, attempt to find the user account in the directory. -->
        <OrchestrationStep Order="7" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>authenticationSource</Value>
              <Value>localAccountAuthentication</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadUsingAlternativeSecurityId" TechnicalProfileReferenceId="AAD-UserReadUsingAlternativeSecurityId-NoError" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- Show self-asserted page only if the directory does not have the user account already (i.e. we do not have an objectId).
              This can only happen when authentication happened using a social IDP. If local account was created or authentication done
              using ESTS in step 2, then an user account must exist in the directory by this time. -->
        <OrchestrationStep Order="8" 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>
        <!-- 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="9" 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="10" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserWrite" TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="11" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
      <ClientDefinition ReferenceId="DefaultWeb" />
    </UserJourney>
 </UserJourneys>
 <SubJourneys>
    <SubJourney Id="PasswordReset" Type="Call">
        <OrchestrationSteps>
            <!--Validate user's email address. Run this step only when user resets the password-->
            <OrchestrationStep Order="1" Type="ClaimsExchange">
              <ClaimsExchanges>
                <ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" />
              </ClaimsExchanges>
            </OrchestrationStep>
            <!--Collect and persist a new password. Run this step only when user resets the password-->
            <OrchestrationStep Order="2" Type="ClaimsExchange">
              <ClaimsExchanges>
                <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
              </ClaimsExchanges>
            </OrchestrationStep>
        </OrchestrationSteps>
    </SubJourney>
 </SubJourneys>