基于用户名登录的Azure B2C:重置密码前先验证认证邮箱
Azure B2C用户名密码重置:提前验证用户名与邮箱匹配的实现方案
完全可行,核心是拆分流程,将用户名+邮箱的匹配验证提前到验证码发送之前,具体配置调整如下:
一、核心思路
当前流程中email声明使用PartnerClaimType="Verified.Email"会让B2C自动触发验证码发送/验证流程,导致邮箱匹配验证被后置。我们需要拆分为三个独立步骤:
- 用户输入用户名和待验证邮箱(普通输入,不触发验证码),提交后立即验证该邮箱是否与账户绑定的强认证邮箱匹配
- 匹配通过后,再触发验证码发送与验证流程
- 验证码验证通过后,执行密码重置
二、具体配置修改
1. 调整账户发现TechnicalProfile(移除自动验证码触发)
修改原LocalAccountDiscoveryUsingUserNameAndValidateStrongAuthenticationEmailAddress,将email改为普通输入字段,避免自动触发验证码:
<TechnicalProfile Id="LocalAccountDiscoveryUsingUserNameAndValidateStrongAuthenticationEmailAddress"> <DisplayName>Enter username and email</DisplayName> <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> <Metadata> <Item Key="IpAddressClaimReferenceId">IpAddress</Item> <Item Key="ContentDefinitionReferenceId">api.selfasserted</Item> <Item Key="AllowGenerationOfClaimsWithNullValues">true</Item> <Item Key="UserMessageIfClaimsTransformationStringsAreNotEqual">The email provided does not match the account's registered email.</Item> <Item Key="UserMessageIfClaimsTransformationBooleanValueIsNotEqual">Your account has been locked. Contact your support person to unlock it, then try again.</Item> <Item Key="LocalAccountType">Username</Item> <Item Key="LocalAccountProfile">true</Item> </Metadata> <CryptographicKeys> ... <!-- 保留原有密钥配置 --> </CryptographicKeys> <OutputClaims> <OutputClaim ClaimTypeReferenceId="signInName" Required="true" /> <OutputClaim ClaimTypeReferenceId="email" Required="true" /> <!-- 移除PartnerClaimType,改为普通输入 --> <OutputClaim ClaimTypeReferenceId="objectId" /> <OutputClaim ClaimTypeReferenceId="strongAuthenticationEmailAddress" /> </OutputClaims> <ValidationTechnicalProfiles> <ValidationTechnicalProfile ReferenceId="AAD-UserReadUsingUserNameAndValidateStrongAuthenticationEmailAddress" /> </ValidationTechnicalProfiles> <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" /> </TechnicalProfile>
2. 保留邮箱匹配验证逻辑
原有的AAD-UserReadUsingUserNameAndValidateStrongAuthenticationEmailAddress和AssertEmailAndstrongAuthenticationEmailAddressAreEqual无需修改。现在用户提交用户名和邮箱后,会立即触发该验证流程,不匹配直接报错,不会进入后续步骤。
3. 添加邮箱验证码验证TechnicalProfile
新增专门处理验证码发送与验证的自断言TechnicalProfile,使用Verified.Email触发自动验证码流程:
<TechnicalProfile Id="LocalAccountVerifyEmail"> <DisplayName>Verify your email</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</Item> <Item Key="UserMessageIfVerificationFailed">The verification code you entered is incorrect.</Item> </Metadata> <OutputClaims> <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" /> <!-- 自动触发验证码 --> </OutputClaims> <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" /> </TechnicalProfile>
4. 更新用户旅程(拆分步骤)
将原单一步骤拆分为三步,确保流程顺序正确:
<UserJourney Id="PasswordResetUsingUsername"> <OrchestrationSteps> <!-- 步骤1:输入用户名和邮箱,验证匹配 --> <OrchestrationStep Order="1" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="LocalAccountDiscoveryExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingUserNameAndValidateStrongAuthenticationEmailAddress" /> </ClaimsExchanges> </OrchestrationStep> <!-- 步骤2:验证邮箱(发送+输入验证码) --> <OrchestrationStep Order="2" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="EmailVerificationExchange" TechnicalProfileReferenceId="LocalAccountVerifyEmail" /> </ClaimsExchanges> </OrchestrationStep> <!-- 步骤3:重置密码(保留原有逻辑) --> <OrchestrationStep Order="3" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="PasswordResetExchange" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep> <!-- 步骤4:结束流程 --> <OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" /> </OrchestrationSteps> <ClientDefinition ReferenceId="DefaultWeb" /> </UserJourney>
三、关键注意事项
- 确保基础策略(如
TrustFrameworkBase.xml)中包含AadSspr-SendCode和AadSspr-VerifyCode,Verified.Email依赖这两个TechnicalProfile处理验证码逻辑 - 可根据实际需求调整
ContentDefinitionReferenceId以匹配自定义页面模板 - 测试时需验证:输入错误邮箱时,提交后立即报错;输入正确邮箱后,才会进入验证码发送环节
内容的提问来源于stack exchange,提问作者Ageonix
相关产品推荐
相关产品推荐

