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

Azure AD B2C自定义策略TOTP设置:二维码不显示且qrCodeContent格式错误

Azure AD B2C自定义策略TOTP二维码无法渲染问题解决

在Azure AD B2C自定义策略中实现TOTP多因素认证时,EnableOTPAuthentication页面的二维码无法渲染,且qrCodeContent声明值格式错误。

当前qrCodeContent值为:

otpauth:totp

期望格式(符合RFC 6238及Google Authenticator规范):

otpauth://totp/test:steveTest@gmail.com?secret=K6L7OZ5P4LJZVQ34&issuer=test

策略详情

  • 租户:test.onmicrosoft.com
  • 策略ID:B2C_1A_TrustFrameworkExtensions
  • 用户旅程:SignUpWithInviteToken
  • 技术配置文件:EnableOTPAuthentication
  • 显示控件:totpQrCodeControl
  • 问题位置:ClaimsTransformation CreateQrCodeUri

问题原因

此前在ClaimsTransformation中添加了以下代码行:

<InputParameter Id="host" DataType="string" Value="totp" />

但BuildUri转换不支持host参数,添加该参数会破坏URI生成逻辑,导致仅保留scheme部分(otpauth:)。

当前相关代码

CreateQrCodeUri转换代码

<ClaimsTransformation Id="CreateQrCodeUri"
                      TransformationMethod="BuildUri">
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="totpLabel" TransformationClaimType="label" />
    <InputClaim ClaimTypeReferenceId="secretKey" TransformationClaimType="secret" />
    <InputClaim ClaimTypeReferenceId="totpIssuer" TransformationClaimType="issuer" />
  </InputClaims>
  <InputParameters>
    <InputParameter Id="scheme" DataType="string" Value="otpauth" />
    <InputParameter Id="path" DataType="string" Value="totp/{label}" />
    <InputParameter Id="querystringParameter1" DataType="string" Value="secret={secret}" />
    <InputParameter Id="querystringParameter2" DataType="string" Value="issuer={issuer}" />
  </InputParameters>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="qrCodeContent" TransformationClaimType="outputClaim" />
  </OutputClaims>
</ClaimsTransformation>

totpQrCodeControl显示控件代码

<DisplayControl Id="totpQrCodeControl" UserInterfaceControlType="QrCodeControl">
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="qrCodeContent" />
  </InputClaims>
  <DisplayClaims>
    <DisplayClaim ClaimTypeReferenceId="qrCodeContent" ControlClaimType="QrCodeContent" />
  </DisplayClaims>
</DisplayControl>

EnableOTPAuthentication技术配置文件代码

<TechnicalProfile Id="EnableOTPAuthentication">
  <DisplayName>Enable Authenticator app</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.totp</Item>
      <Item Key="language.button_continue">Continue</Item>
  </Metadata>
  <CryptographicKeys>
      <Key Id="issuer_secret"
           StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
  </CryptographicKeys>
  <InputClaimsTransformations>
      <!-- Set secretKey first -->
      <InputClaimsTransformation ReferenceId="CopyInviteTokenToSecretKey" />
      <!-- Set totpIssuer (static or from claim) -->
      <InputClaimsTransformation ReferenceId="SetTotpIssuer" />
      <!-- Format totpLabel -->
      <InputClaimsTransformation ReferenceId="FormatTotpLabel" />
      <!-- Build the QR code URI -->
      <InputClaimsTransformation ReferenceId="CreateQrCodeUri" />
  </InputClaimsTransformations>
  <InputClaims>
      <InputClaim ClaimTypeReferenceId="QrCodeScanInstruction"
                  DefaultValue="Scan this QR code with your Authenticator app" />
      <InputClaim ClaimTypeReferenceId="qrCodeContent" />
      <InputClaim ClaimTypeReferenceId="secretKey" />
      <InputClaim ClaimTypeReferenceId="totpIssuer" />
  </InputClaims>
  <DisplayClaims>
      <DisplayClaim DisplayControlReferenceId="authenticatorAppIconControl" />
      <DisplayClaim ClaimTypeReferenceId="QrCodeScanInstruction" />
      <DisplayClaim DisplayControlReferenceId="totpQrCodeControl" />
      <DisplayClaim DisplayControlReferenceId="authenticatorInfoControl" />
  </DisplayClaims>
  <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="objectId" />
      <OutputClaim ClaimTypeReferenceId="secretKey" />
      <OutputClaim ClaimTypeReferenceId="qrCodeContent" />
  </OutputClaims>
  <UseTechnicalProfileForSessionManagement ReferenceId="SM-MFA-TOTP" />
</TechnicalProfile>

TOTP-Verify技术配置文件代码

<TechnicalProfile Id="TOTP-Verify">
    <DisplayName>Verify Authenticator code</DisplayName>
    <Protocol Name="Proprietary"
              Handler="Web.TPEngine.Providers.TotpProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    <Metadata>
        <Item Key="ManualCodeEntryAllowed">true</Item>
        <Item Key="EnforceVerification">true</Item>
    </Metadata>
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="userId" />
    </InputClaims>
    <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="totpSecret" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource"
                     DefaultValue="totp" />
    </OutputClaims>
</TechnicalProfile>

解决方法

由于BuildUri转换不支持host参数,需调整CreateQrCodeUri的配置,将host部分整合到path参数中,以此生成符合规范的otpauth URI。

修改后的CreateQrCodeUri代码:

<ClaimsTransformation Id="CreateQrCodeUri"
                      TransformationMethod="BuildUri">
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="totpLabel" TransformationClaimType="label" />
    <InputClaim ClaimTypeReferenceId="secretKey" TransformationClaimType="secret" />
    <InputClaim ClaimTypeReferenceId="totpIssuer" TransformationClaimType="issuer" />
  </InputClaims>
  <InputParameters>
    <InputParameter Id="scheme" DataType="string" Value="otpauth" />
    <InputParameter Id="path" DataType="string" Value="//totp/{label}" />
    <InputParameter Id="querystringParameter1" DataType="string" Value="secret={secret}" />
    <InputParameter Id="querystringParameter2" DataType="string" Value="issuer={issuer}" />
  </InputParameters>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="qrCodeContent" TransformationClaimType="outputClaim" />
  </OutputClaims>
</ClaimsTransformation>

同时需确保以下声明值正确:

  • totpLabel需为{issuer}:{username}格式(如test:steveTest@gmail.com)
  • secretKey必须是有效的Base32编码密钥
  • totpIssuer需与URI中的issuer参数值一致

修改后重新发布策略,qrCodeContent将生成符合期望的格式,二维码即可正常渲染。

内容的提问来源于stack exchange,提问作者Ret 2

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 19:45:56