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

如何在AAD B2C自定义策略的统一登录页添加reCaptcha

在Azure AD B2C统一登录页(unified.html)添加Google reCaptcha并验证

核心问题说明

统一登录页(ContentDefinition为api.signuporsignin,基于unifiedssp契约)与自断言页面(api.selfasserted)的渲染逻辑不同,无法直接通过声明字段自动渲染reCaptcha控件,需手动在自定义HTML中添加控件并通过JavaScript将验证结果传递给B2C策略。


步骤1:定义reCaptcha响应声明

在策略的<ClaimsSchema>节点下添加以下声明,用于存储reCaptcha的验证响应:

<ClaimType Id="g-recaptcha-response-toms">
  <DisplayName>Google reCaptcha响应值</DisplayName>
  <DataType>string</DataType>
  <AdminHelpText>存储Google reCaptcha的验证token</AdminHelpText>
</ClaimType>

<!-- 可选:添加用于验证结果的声明 -->
<ClaimType Id="recaptchaSuccess">
  <DisplayName>reCaptcha验证结果</DisplayName>
  <DataType>boolean</DataType>
</ClaimType>

步骤2:修改自定义unified.html页面

在你的自定义登录页中,完成以下操作:

  1. 引入Google reCaptcha脚本:在HTML的<head>或<body>末尾添加reCaptcha加载脚本:
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
    
  2. 添加reCaptcha控件:在登录表单的密码字段后插入reCaptcha控件(替换YOUR_RECAPTCHA_SITE_KEY为你的站点密钥):
    <div class="form-group">
      <label class="control-label">验证</label>
      <div class="g-recaptcha" data-sitekey="YOUR_RECAPTCHA_SITE_KEY"></div>
    </div>
    
  3. 添加提交处理脚本:监听表单提交事件,将reCaptcha响应值存入B2C对应的声明字段:
    document.addEventListener('DOMContentLoaded', function() {
      const loginForm = document.querySelector('form');
      if (loginForm) {
        loginForm.addEventListener('submit', function(e) {
          // 获取reCaptcha响应token
          const recaptchaToken = grecaptcha.getResponse();
          
          // 查找或创建隐藏输入框,绑定到声明字段
          let recaptchaInput = loginForm.querySelector('input[name="g-recaptcha-response-toms"]');
          if (!recaptchaInput) {
            recaptchaInput = document.createElement('input');
            recaptchaInput.type = 'hidden';
            recaptchaInput.name = 'g-recaptcha-response-toms';
            loginForm.appendChild(recaptchaInput);
          }
          recaptchaInput.value = recaptchaToken;
          
          // 未完成验证则阻止提交
          if (!recaptchaToken) {
            e.preventDefault();
            alert('请完成人机验证');
          }
        });
      }
    });
    

步骤3:调整自断言技术配置文件

确保SelfAsserted-LocalAccountSignin-Username技术配置文件中正确包含reCaptcha声明:

  • 在<OutputClaims>中保留g-recaptcha-response-toms并标记为必填:
    <OutputClaim ClaimTypeReferenceId="g-recaptcha-response-toms" Required="true" />
    
  • 确保<ValidationTechnicalProfiles>中login-Recaptcha排在login-NonInteractive之前,先验证reCaptcha再执行登录逻辑。

步骤4:配置reCaptcha验证技术配置文件

确保login-Recaptcha技术配置文件正确调用Google验证API(替换YOUR_RECAPTCHA_SECRET_KEY为你的密钥):

<TechnicalProfile Id="login-Recaptcha">
  <DisplayName>Google reCaptcha验证</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ServiceUrl">https://www.google.com/recaptcha/api/siteverify?secret=YOUR_RECAPTCHA_SECRET_KEY</Item>
    <Item Key="SendClaimsIn">Form</Item>
    <Item Key="AllowInsecureAuthInProduction">false</Item>
  </Metadata>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="g-recaptcha-response-toms" PartnerClaimType="response" />
    <InputClaim ClaimTypeReferenceId="clientIpAddress" PartnerClaimType="remoteip" />
  </InputClaims>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="recaptchaSuccess" PartnerClaimType="success" />
  </OutputClaims>
  <ValidationClaimsTransformations>
    <ValidationClaimsTransformation ReferenceId="AssertRecaptchaSuccessIsTrue" />
  </ValidationClaimsTransformations>
  <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>

<!-- 添加断言验证转换 -->
<ClaimsTransformation Id="AssertRecaptchaSuccessIsTrue" TransformationMethod="AssertBooleanClaimIsEqualToValue">
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="recaptchaSuccess" TransformationClaimType="inputClaim" />
  </InputClaims>
  <InputParameters>
    <InputParameter Id="valueToCompareTo" DataType="boolean" Value="true" />
  </InputParameters>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="recaptchaSuccess" />
  </OutputClaims>
  <OutputClaimsTransformations>
    <OutputClaimsTransformation ReferenceId="CreateRecaptchaFailureError" />
  </OutputClaimsTransformations>
</ClaimsTransformation>

<ClaimsTransformation Id="CreateRecaptchaFailureError" TransformationMethod="CreateStringClaim">
  <InputParameters>
    <InputParameter Id="value" DataType="string" Value="人机验证失败,请重试" />
  </InputParameters>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="errorMessage" TransformationClaimType="createdClaim" />
  </OutputClaims>
</ClaimsTransformation>

关键注意事项

  • 确保Google reCaptcha控制台已将你的B2C自定义域名添加到授权域名列表。
  • 统一登录页不会自动渲染未在B2C预定义字段中的控件,必须手动添加并通过JS绑定声明值。
  • 验证失败时,需通过ClaimsTransformation抛出友好错误提示,避免用户看到原始API错误。

内容的提问来源于stack exchange,提问作者Patrice Cote

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:45:19