保留 strongAuthenticationEmailAddress,在 Azure B2C 自定义策略中重置 strongAuthenticationPhoneNumber,反之亦然

Persisting strongAuthenticationEmailAddress, resets strongAuthenticationPhoneNumber and vice-versa in Azure B2C custom policy

我能够通过修改策略扩展文件中定义的 'ProfileEditWithUsername' 用户旅程来编辑“strongAuthenticationEmailAddress”(https://github.com/azure-ad-b2c/samples/tree/master/policies/username-signup-or-signin)。我将 strongAuthenticationEmailAddress 保留在 'AAD-UserWriteProfileUsingObjectId' 技术配置文件中,上述用户旅程将其用作编排步骤 4 中的验证配置文件。

但是,我注意到如果我 运行 更改 strongAuthenticationEmailAddress 的策略,电子邮件已成功更改,但 strongAuthenticationPhoneNumber 和备用 phone(用于身份验证)被设置为空白。 同样,我实施了 edit-MFA phone 号码策略 (https://github.com/azure-ad-b2c/samples/tree/master/policies/edit-mfa-phone-number),并使用它我能够编辑 strongAuthenticationPhoneNumber,但它会将 strongAuthenticationEmailAddress 设置为空白。

<UserJourney Id="ProfileEditWithUsername">
    <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsProviderSelection" ContentDefinitionReferenceId="api.idpselections">
            <ClaimsProviderSelections>
                <ClaimsProviderSelection TargetClaimsExchangeId="LocalAccountSigninUsernameExchange" />
            </ClaimsProviderSelections>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
            <ClaimsExchanges>
                <ClaimsExchange Id="LocalAccountSigninUsernameExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Username" />
            </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="ClaimsExchange">
            <ClaimsExchanges>
                <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
            </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="4" Type="ClaimsExchange">
            <ClaimsExchanges>
                <ClaimsExchange Id="B2CUserProfileUpdateExchange" TechnicalProfileReferenceId="SelfAsserted-ProfileUpdate" />
            </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="5" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
    </OrchestrationSteps>
    <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>

--------------------------------------------------
<TechnicalProfile Id="AAD-UserReadUsingObjectId">
    <Metadata>
        <Item Key="Operation">Read</Item>
        <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
    </Metadata>
    <IncludeInSso>false</IncludeInSso>
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
    </InputClaims>
    <OutputClaims>
        <!-- Required claims -->
        <OutputClaim ClaimTypeReferenceId="strongAuthenticationPhoneNumber" />
        <OutputClaim ClaimTypeReferenceId="strongAuthenticationEmailAddress" />

        <!-- Optional claims -->
        <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" />
        <OutputClaim ClaimTypeReferenceId="displayName" />
        <OutputClaim ClaimTypeReferenceId="otherMails" />
        <OutputClaim ClaimTypeReferenceId="givenName" />
        <OutputClaim ClaimTypeReferenceId="surname" />

    </OutputClaims>
    <IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>
-------------------------------------------------
<TechnicalProfile Id="SelfAsserted-ProfileUpdate">
    <DisplayName>User ID signup</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.profileupdate</Item>
    </Metadata>
    <IncludeInSso>false</IncludeInSso>
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="alternativeSecurityId" />
        <InputClaim ClaimTypeReferenceId="userPrincipalName" />
        <!-- Optional claims. These claims are collected from the user and can be modified. Any claim added here should be updated in the
                 ValidationTechnicalProfile referenced below so it can be written to directory after being updateed by the user, i.e. AAD-UserWriteProfileUsingObjectId. -->
        <InputClaim ClaimTypeReferenceId="givenName" />
        <InputClaim ClaimTypeReferenceId="surname" />
        <InputClaim ClaimTypeReferenceId="strongAuthenticationEmailAddress" />


    </InputClaims>
    <OutputClaims>
        <!-- Required claims -->
        <OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" />
        <!-- Optional claims. These claims are collected from the user and can be modified. Any claim added here should be updated in the
                 ValidationTechnicalProfile referenced below so it can be written to directory after being updateed by the user, i.e. AAD-UserWriteProfileUsingObjectId. -->
        <OutputClaim ClaimTypeReferenceId="givenName" />
        <OutputClaim ClaimTypeReferenceId="surname" />
        <OutputClaim ClaimTypeReferenceId="strongAuthenticationEmailAddress" />


    </OutputClaims>
    <ValidationTechnicalProfiles>
        <ValidationTechnicalProfile ReferenceId="AAD-UserWriteProfileUsingObjectId" />
    </ValidationTechnicalProfiles>
</TechnicalProfile>
---------------------------------------------------------------------------
<TechnicalProfile Id="AAD-UserWriteProfileUsingObjectId">
    <Metadata>
        <Item Key="Operation">Write</Item>
        <Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item>
        <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
    </Metadata>
    <IncludeInSso>false</IncludeInSso>
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
    </InputClaims>
    <PersistedClaims>
        <!-- Required claims -->
        <PersistedClaim ClaimTypeReferenceId="objectId" />

        <!-- Optional claims -->
        <PersistedClaim ClaimTypeReferenceId="givenName" />
        <PersistedClaim ClaimTypeReferenceId="surname" />
        <PersistedClaim ClaimTypeReferenceId="strongAuthenticationEmailAddress" />

    </PersistedClaims>
    <IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>

我记得我遇到过同样令人沮丧的问题。

如果您在 TechnicalProfile 中保留其中一个 strongAuthentication 字段,它将清除任何其他 strongAuthentication 字段,除非您也保留这些字段。

因此,无论您在何处坚持一个 strongAuthentication 字段,都改为坚持它们。在您的示例中,您的技术资料“AAD-UserWriteProfileUsingObjectId”应如下所示:

<TechnicalProfile Id="AAD-UserWriteProfileUsingObjectId">
<Metadata>
    <Item Key="Operation">Write</Item>
    <Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item>
    <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
    <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
</InputClaims>
<PersistedClaims>
    <!-- Required claims -->
    <PersistedClaim ClaimTypeReferenceId="objectId" />

    <!-- Optional claims -->
    <PersistedClaim ClaimTypeReferenceId="givenName" />
    <PersistedClaim ClaimTypeReferenceId="surname" />
    <PersistedClaim ClaimTypeReferenceId="strongAuthenticationEmailAddress" />
    
    <!-- *** NEW LINE *** -->
    <PersistedClaim ClaimTypeReferenceId="strongAuthenticationPhoneNumber" />
</PersistedClaims>
<IncludeTechnicalProfile ReferenceId="AAD-Common" />

请注意在 PersistedClaims 中为 strongAuthenticationPhoneNumber 添加的新行。

模式中的另一个地方会发生这种情况,它与 signInNames 集合有关。如果你坚持 signInNames.username 之类的东西,它会清除任何其他登录名(比如 signInNames.emailaddress),除非你也坚持 signInNames.emailaddress,所以也要注意这一点。