You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于用户名登录的Azure B2C:重置密码前先验证认证邮箱

Azure B2C用户名密码重置:提前验证用户名与邮箱匹配的实现方案

完全可行,核心是拆分流程,将用户名+邮箱的匹配验证提前到验证码发送之前,具体配置调整如下:

一、核心思路

当前流程中email声明使用PartnerClaimType="Verified.Email"会让B2C自动触发验证码发送/验证流程,导致邮箱匹配验证被后置。我们需要拆分为三个独立步骤:

  1. 用户输入用户名和待验证邮箱(普通输入,不触发验证码),提交后立即验证该邮箱是否与账户绑定的强认证邮箱匹配
  2. 匹配通过后,再触发验证码发送与验证流程
  3. 验证码验证通过后,执行密码重置

二、具体配置修改

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 03:35:34