Azure B2C:从单独的登录步骤访问时,注册页面出错

Posted

技术标签:

【中文标题】Azure B2C:从单独的登录步骤访问时,注册页面出错【英文标题】:Azure B2C: Error on sign up page when accessed from separated sign in step 【发布时间】:2022-01-19 17:25:59 【问题描述】:

我一直在尝试创建与 B2C 登录/注册示例略有不同的 UI 流程,但这会导致注册页面出现错误。到目前为止的工作如下:我一直在使用此处提供的示例 https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/blob/master/SocialAndLocalAccounts/TrustFrameworkBase.xml 并进行了一些修改(例如使用 Azure AD 进行社交登录,而不是 Facebook)。我正在使用以下技术资料:

<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email">
      <DisplayName>Local Account Signin</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="SignUpTarget">SignUpWithLogonEmailExchange</Item>
        <Item Key="setting.operatingMode">Email</Item>
        <Item Key="ContentDefinitionReferenceId">api.localaccountsignin</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="email" Required="true" />
        <OutputClaim ClaimTypeReferenceId="password" Required="true" />
        <OutputClaim ClaimTypeReferenceId="objectId" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" />
      </OutputClaims>
      <ValidationTechnicalProfiles>
        <ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
      </ValidationTechnicalProfiles>
    </TechnicalProfile>

这些是前两个编排步骤:

    <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
      <ClaimsProviderSelections>
        <ClaimsProviderSelection TargetClaimsExchangeId="AzureADExchange" />
        <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
      </ClaimsProviderSelections>
      <ClaimsExchanges>
        <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="2" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>objectId</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AzureADExchange" TechnicalProfileReferenceId="Multi-TenantAAD" />
        <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
      </ClaimsExchanges>
    </OrchestrationStep>

当我运行策略时,会出现以下屏幕:Email sign in or sign up plus social sign in

当我点击注册按钮时,会出现这个屏幕:Email sign up

这一切都很好,并且工作正常。但是,我想更改它,以便初始屏幕只是一个用于 Microsoft 登录的按钮和一个用于电子邮件登录的按钮。然后单击电子邮件登录后,它会将您带到登录/注册页面。因此我做了以下修改:

我已更改技术配置文件中的内容定义参考:

<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email">
      <DisplayName>Sign In With Email</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="SignUpTarget">SignUpWithLogonEmailExchange</Item>
        <Item Key="setting.operatingMode">Email</Item>
        <Item Key="ContentDefinitionReferenceId">api.signuporsignin</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="email" Required="true" />
        <OutputClaim ClaimTypeReferenceId="password" Required="true" />
        <OutputClaim ClaimTypeReferenceId="objectId" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" />
      </OutputClaims>
      <ValidationTechnicalProfiles>
        <ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
      </ValidationTechnicalProfiles>
    </TechnicalProfile>

我已经更改了编排步骤:

<OrchestrationStep Order="1" Type="ClaimsProviderSelection" ContentDefinitionReferenceId="api.idpselections">
      <ClaimsProviderSelections>
        <ClaimsProviderSelection TargetClaimsExchangeId="AzureADExchange" />
        <ClaimsProviderSelection TargetClaimsExchangeId="LocalAccountSigninEmailExchange" />
      </ClaimsProviderSelections>
    </OrchestrationStep>

    <OrchestrationStep Order="2" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="AzureADExchange" TechnicalProfileReferenceId="Multi-TenantAAD" />
        <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="3" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>objectId</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
          <Value>authenticationSource</Value>
          <Value>socialIdpAuthentication</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
      </ClaimsExchanges>
    </OrchestrationStep>

第一步现在只是一个 ClaimsProviderSelection,目标位于第二步。

现在发生的情况是,当您运行策略时,您会看到:Social or Email selection

点击电子邮件登录后,您会看到:Email sign in or sign up

这正是我想要的,两种登录方法都可以正常工作。但是,现在的问题是,如果您单击注册按钮,而不是进入注册页面,而是看到此页面:Sorry we're having trouble signing you in

您知道是什么原因造成的以及如何解决吗?我一直在尝试许多不同的设置或配置编排步骤的方法,但它们似乎都没有帮助。我确定本地帐户登录技术配置文件连接回电子邮件注册声明交换的方式存在问题,但我不知道如何正确连接它们。

【问题讨论】:

【参考方案1】:

这里有一个解决方案,而不是尝试像启动包那样启动它,而是让我们调用技术配置文件来标记我们想要前进的方向,无论是联合 IdP,还是通过正常的组合登录和注册步骤.

要使登录页面与注册页面对话,它们必须像入门包一样排列,使用Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin"

  <BuildingBlocks>
    <ClaimsSchema>
      <ClaimType Id="Exchange">
        <DisplayName>Exchange</DisplayName>
        <DataType>string</DataType>
        <UserHelpText />
      </ClaimType>
    </ClaimsSchema>
  </BuildingBlocks>
  <ClaimsProviders>
    <ClaimsProvider>
      <DisplayName>SetExchangeValues</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="Set-ContosoExchange">
          <DisplayName>Microsoft account</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="Exchange" DefaultValue="Contoso" />
          </OutputClaims>
        </TechnicalProfile>
        <TechnicalProfile Id="Set-LocalExchange">
          <DisplayName>Sign in with email</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="Exchange" DefaultValue="LocalSUSI" />
          </OutputClaims>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
  </ClaimsProviders>
  <UserJourneys>
    <UserJourney Id="idptest">
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsProviderSelection" ContentDefinitionReferenceId="api.idpselections">
          <ClaimsProviderSelections>
            <ClaimsProviderSelection TargetClaimsExchangeId="ContosoExchange" />
            <ClaimsProviderSelection TargetClaimsExchangeId="LocalAccountSigninEmailExchange" />
          </ClaimsProviderSelections>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="ContosoExchange" TechnicalProfileReferenceId="Set-ContosoExchange" />
            <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="Set-LocalExchange" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
              <Value>Exchange</Value>
              <Value>LocalSUSI</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsProviderSelections>
            <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange-TP" />
          </ClaimsProviderSelections>
          <ClaimsExchanges>
            <ClaimsExchange Id="LocalAccountSigninEmailExchange-TP" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="4" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
              <Value>Exchange</Value>
              <Value>LocalSUSI</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="5" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
              <Value>Exchange</Value>
              <Value>Contoso</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="AzureADExchange" TechnicalProfileReferenceId="Multi-TenantAAD" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
      <ClientDefinition ReferenceId="DefaultWeb" />
    </UserJourney>
  </UserJourneys>

【讨论】:

工作出色,谢谢! 其实,也许我说得太早了。我现在正在尝试按照本指南添加自助服务密码重置功能:docs.microsoft.com/en-us/azure/active-directory-b2c/…,但是在进入注册页面时流程会产生另一个错误。你知道我该如何解决这个问题吗?

以上是关于Azure B2C:从单独的登录步骤访问时,注册页面出错的主要内容,如果未能解决你的问题,请参考以下文章

90 天后访问 Azure B2C 登录日志

是否可以强制禁用 Azure AD B2c 中的访问令牌?

如何从 Azure B2C 获取 ASPCore 中的 OID 声明

在 Postman 中为 Azure AD B2C 请求访问令牌

如何向 azure b2c 访问令牌添加自定义声明?

更改 Azure AD B2C 访问令牌生命周期不起作用