如何在Azure AD B2C中配置多用户可选MFA注册方式?
可以在Azure AD B2C中实现用户配置多种可选MFA注册方式(主、次方案),但需要通过自定义策略实现(内置策略仅支持单一可选MFA方式,如你提到的mfa-email-or-phone)。以下是具体技术实现步骤:
基础准备
- 已部署Azure AD B2C自定义策略框架(包含
TrustFrameworkBase.xml、TrustFrameworkExtensions.xml、SignUpSignIn.xml) - 熟悉自定义策略的
ClaimsProviders、UserJourneys、OrchestrationSteps核心配置逻辑
1. 添加多类型MFA声明提供者
在TrustFrameworkExtensions.xml的<ClaimsProviders>节点下,添加多种MFA方式的技术配置,示例包含电话、邮件、微软Authenticator应用三种:
<!-- 电话MFA --> <ClaimsProvider> <DisplayName>Phone Factor</DisplayName> <TechnicalProfiles> <TechnicalProfile Id="PhoneFactor-InputOrVerify"> <DisplayName>Phone Verification</DisplayName> <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.PhoneFactorProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> <Metadata> <Item Key="ContentDefinitionReferenceId">api.phonefactor</Item> </Metadata> <CryptographicKeys> <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" /> </CryptographicKeys> <InputClaims> <InputClaim ClaimTypeReferenceId="userId" PartnerClaimType="UserId" /> <InputClaim ClaimTypeReferenceId="phoneNumber" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="verified.phoneNumber" PartnerClaimType="VerifiedPhoneNumber" /> <OutputClaim ClaimTypeReferenceId="phoneNumber" /> </OutputClaims> <UseTechnicalProfileForSessionManagement ReferenceId="SM-MFA" /> </TechnicalProfile> </TechnicalProfiles> </ClaimsProvider> <!-- 邮件MFA --> <ClaimsProvider> <DisplayName>Email Verification</DisplayName> <TechnicalProfiles> <TechnicalProfile Id="EmailVerifyOnSignup"> <DisplayName>Email Verification</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> <Item Key="EnforceEmailVerification">True</Item> </Metadata> <InputClaims> <InputClaim ClaimTypeReferenceId="email" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" /> </OutputClaims> </TechnicalProfile> </TechnicalProfiles> </ClaimsProvider> <!-- 微软Authenticator应用MFA --> <ClaimsProvider> <DisplayName>Microsoft Authenticator</DisplayName> <TechnicalProfiles> <TechnicalProfile Id="MicrosoftAuthenticator-SignupOrVerify"> <DisplayName>Microsoft Authenticator</DisplayName> <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.MicrosoftAuthenticatorProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> <Metadata> <Item Key="ContentDefinitionReferenceId">api.microsoftauthenticator</Item> </Metadata> <InputClaims> <InputClaim ClaimTypeReferenceId="userId" PartnerClaimType="UserId" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="microsoftAuthenticatorAccountId" /> </OutputClaims> <UseTechnicalProfileForSessionManagement ReferenceId="SM-MFA" /> </TechnicalProfile> </TechnicalProfiles> </ClaimsProvider>
2. 定义主次MFA声明类型
在TrustFrameworkBase.xml的<ClaimTypes>节点下,添加用于存储用户主次MFA方式的声明:
<ClaimType Id="mfaPrimaryMethod"> <DisplayName>Primary MFA Method</DisplayName> <DataType>string</DataType> <UserInputType>DropdownSingleSelect</UserInputType> <Restriction> <Enumeration Text="Phone" Value="phone" /> <Enumeration Text="Email" Value="email" /> <Enumeration Text="Authenticator App" Value="authenticator" /> </Restriction> </ClaimType> <ClaimType Id="mfaSecondaryMethod"> <DisplayName>Secondary MFA Method</DisplayName> <DataType>string</DataType> <UserInputType>DropdownSingleSelect</UserInputType> <Restriction> <Enumeration Text="None" Value="none" /> <Enumeration Text="Phone" Value="phone" /> <Enumeration Text="Email" Value="email" /> <Enumeration Text="Authenticator App" Value="authenticator" /> </Restriction> </ClaimType>
3. 配置注册流程:允许用户选择并注册主次MFA方式
在TrustFrameworkExtensions.xml的<UserJourneys>节点中,修改注册流程的OrchestrationSteps,添加以下核心步骤:
- 收集用户基本信息后,让用户选择主MFA方式,并完成对应方式的注册验证
- 提供选项让用户选择次MFA方式(可选为"None"),若选择非"None",则完成对应方式的注册验证
示例步骤片段:
<!-- 步骤:选择主MFA方式 --> <OrchestrationStep Order="4" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="SelectPrimaryMFA" TechnicalProfileReferenceId="SelfAsserted-SelectPrimaryMFA" /> </ClaimsExchanges> </OrchestrationStep> <!-- 步骤:根据主MFA方式执行验证注册 --> <OrchestrationStep Order="5" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimEquals" ExecuteActionsIf="true"> <Value>mfaPrimaryMethod</Value> <Value>phone</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> <Precondition Type="ClaimEquals" ExecuteActionsIf="true"> <Value>mfaPrimaryMethod</Value> <Value>email</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> <Precondition Type="ClaimEquals" ExecuteActionsIf="true"> <Value>mfaPrimaryMethod</Value> <Value>authenticator</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="PrimaryPhoneMFA" TechnicalProfileReferenceId="PhoneFactor-InputOrVerify" /> <ClaimsExchange Id="PrimaryEmailMFA" TechnicalProfileReferenceId="EmailVerifyOnSignup" /> <ClaimsExchange Id="PrimaryAuthenticatorMFA" TechnicalProfileReferenceId="MicrosoftAuthenticator-SignupOrVerify" /> </ClaimsExchanges> </OrchestrationStep> <!-- 步骤:选择次MFA方式 --> <OrchestrationStep Order="6" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="SelectSecondaryMFA" TechnicalProfileReferenceId="SelfAsserted-SelectSecondaryMFA" /> </ClaimsExchanges> </OrchestrationStep> <!-- 步骤:根据次MFA方式执行验证注册(仅当选择非None时) --> <OrchestrationStep Order="7" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimEquals" ExecuteActionsIf="true"> <Value>mfaSecondaryMethod</Value> <Value>none</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="SecondaryPhoneMFA" TechnicalProfileReferenceId="PhoneFactor-InputOrVerify" /> <ClaimsExchange Id="SecondaryEmailMFA" TechnicalProfileReferenceId="EmailVerifyOnSignup" /> <ClaimsExchange Id="SecondaryAuthenticatorMFA" TechnicalProfileReferenceId="MicrosoftAuthenticator-SignupOrVerify" /> </ClaimsExchanges> </OrchestrationStep>
注:需自行定义SelfAsserted-SelectPrimaryMFA和SelfAsserted-SelectSecondaryMFA这两个自断言技术配置,用于渲染用户选择MFA方式的UI。
4. 配置登录流程:优先主MFA, fallback到次MFA
在登录流程的OrchestrationSteps中,先读取用户存储的mfaPrimaryMethod,优先验证主MFA方式;若验证失败(或用户选择切换),则提供次MFA方式的验证选项:
<!-- 步骤:尝试主MFA验证 --> <OrchestrationStep Order="3" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="PrimaryMFA-Verify" TechnicalProfileReferenceId="PrimaryMFA-VerifyHandler" /> </ClaimsExchanges> </OrchestrationStep> <!-- 步骤:主MFA失败后,提供次MFA验证选项(若用户已注册次方式) --> <OrchestrationStep Order="4" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimEquals" ExecuteActionsIf="true"> <Value>mfaSecondaryMethod</Value> <Value>none</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> <Precondition Type="ClaimsExist" ExecuteActionsIf="true"> <Value>isPrimaryMFAVerified</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="SecondaryMFA-Verify" TechnicalProfileReferenceId="SecondaryMFA-VerifyHandler" /> </ClaimsExchanges> </OrchestrationStep>
注:PrimaryMFA-VerifyHandler和SecondaryMFA-VerifyHandler需根据用户存储的MFA方式动态调用对应的验证技术配置,可通过ClaimsTransformation或预条件判断实现。
5. 持久化用户MFA方式信息
在SignUpSignIn.xml的<RelyingParty>节点下,添加以下<PersistedClaims>,确保主次MFA方式信息存储到Azure AD B2C用户目录:
<PersistedClaims> <PersistedClaim ClaimTypeReferenceId="mfaPrimaryMethod" /> <PersistedClaim ClaimTypeReferenceId="mfaSecondaryMethod" /> <!-- 其他需要持久化的声明 --> </PersistedClaims>
关键注意事项
- 自定义UI需配合调整,确保用户选择MFA方式的界面清晰易懂
- 需处理用户未注册次MFA的场景,登录流程仅显示主方式
- 测试时需覆盖主MFA验证成功、失败后切换次MFA、次MFA未配置等多种场景
内容的提问来源于stack exchange,提问作者HXK8

