首页 > 解决方案 > 自定义策略以 oauth2/authresp 上的错误 500 结束

问题描述

我想为我的应用程序提供 2 个登录提供程序。客户将与 B2C 连接,员工将通过 SSO 与我们的 AAD 连接。目前,客户的 B2C 登录适用于 SignIn V2 用户流程,我们的 SSO 也适用于任何其他应用程序。

我按照这两个页面开始使用,使用完全相同的名称:

它们可能更清楚,但我认为就 XML 而言我做的一切都是正确的。当我运行我的自定义策略时,我会得到一个页面,其中包含一个登录表单和一个用于连接 AD 的按钮。如果单击该按钮,我将被重定向到 SSO 页面并使用我的用户登录。我第一次被要求接受权限。到目前为止一切顺利,但之后我被重定向到https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/oauth2/authresp,它给出了一个通用错误 500 页面。在 B2C 审核日志中,我看到一个事件“与身份提供者联合”和“状态:成功”,与我登录的日期时间相同,所以我相信登录有效。同样,我可以在 AAD 中的用户页面中看到成功登录。

MSDN页面错过了我需要做的更多事情吗?我应该使用令牌重定向到 jwt.ms。

相关 xml 文件(已编辑):TrustFrameworkBase.xml(仅我修改过的部分):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TrustFrameworkPolicy
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
  PolicySchemaVersion="0.3.0.0"
  TenantId="mytenant.onmicrosoft.com"
  PolicyId="B2C_1A_TrustFrameworkBase"
  PublicPolicyUri="http://mytenant.onmicrosoft.com/B2C_1A_TrustFrameworkBase">

    <!-- snip default building blocks -->

    <ClaimsProviders>
        <ClaimsProvider>
            <DisplayName>Local Account SignIn</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="login-NonInteractive">
                    <DisplayName>Local Account SignIn</DisplayName>
                    <Protocol Name="OpenIdConnect" />
                    <Metadata>
                        <Item Key="UserMessageIfClaimsPrincipalDoesNotExist">We can't seem to find your account</Item>
                        <Item Key="UserMessageIfInvalidPassword">Your password is incorrect</Item>
                        <Item Key="UserMessageIfOldPasswordUsed">Looks like you used an old password</Item>

                        <Item Key="ProviderName">https://sts.windows.net/mytenantguid/</Item>
                        <Item Key="METADATA">https://login.microsoftonline.com/mytenant.onmicrosoft.com/.well-known/openid-configuration</Item>
                        <Item Key="authorization_endpoint">https://login.microsoftonline.com/mytenant.onmicrosoft.com/oauth2/token</Item>
                        <Item Key="response_types">id_token</Item>
                        <Item Key="response_mode">query</Item>
                        <Item Key="scope">email openid</Item>

                        <!-- Policy Engine Clients -->
                        <Item Key="UsePolicyInRedirectUri">false</Item>
                        <Item Key="HttpBinding">POST</Item>
                    </Metadata>
                    <InputClaims>
                        <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="username" Required="true" />
                        <InputClaim ClaimTypeReferenceId="password" Required="true" />
                        <InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="password" />
                        <InputClaim ClaimTypeReferenceId="scope" DefaultValue="openid" />
                        <InputClaim ClaimTypeReferenceId="nca" PartnerClaimType="nca" DefaultValue="1" />
                    </InputClaims>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid" />
                        <OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid" />
                        <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
                        <OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
                        <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
                        <OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" />
                        <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" />
                    </OutputClaims>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>

       <!-- snip other default claim providers-->
       <!-- snip default user journeys-->      
</TrustFrameworkPolicy>

TrustFrameworkExtension.xml

<?xml version="1.0" encoding="utf-8" ?>
<TrustFrameworkPolicy
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
  PolicySchemaVersion="0.3.0.0"
  TenantId="mytenant.onmicrosoft.com"
  PolicyId="B2C_1A_TrustFrameworkExtensions"
  PublicPolicyUri="http://mytenant.onmicrosoft.com/B2C_1A_TrustFrameworkExtensions">

    <BasePolicy>
        <TenantId>mytenant.onmicrosoft.com</TenantId>
        <PolicyId>B2C_1A_TrustFrameworkBase</PolicyId>
    </BasePolicy>
    <BuildingBlocks>
    </BuildingBlocks>

    <ClaimsProviders>

        <ClaimsProvider>
            <DisplayName>Local Account SignIn</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="login-NonInteractive">
                    <Metadata>
                        <Item Key="client_id">ProxyIdentityExperienceFramework_AppId</Item>
                        <Item Key="IdTokenAudience">IdentityExperienceFramework_AppId</Item>
                    </Metadata>
                    <InputClaims>
                        <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="ProxyIdentityExperienceFramework_AppId" />
                        <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="IdentityExperienceFramework_AppId" />
                    </InputClaims>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>

        <ClaimsProvider>
            <Domain>Mycompany</Domain>
            <DisplayName>Login using Mycompany</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="MycompanyProfile">
                    <DisplayName>Mycompany Employee</DisplayName>
                    <Description>Login with your Mycompany account</Description>
                    <Protocol Name="OpenIdConnect"/>
                    <OutputTokenFormat>JWT</OutputTokenFormat>
                    <Metadata>
                        <Item Key="METADATA">https://login.windows.net/mytenant.onmicrosoft.com/.well-known/openid-configuration</Item>
                        <Item Key="ProviderName">https://sts.windows.net/mytenantguid/</Item>
                        <Item Key="client_id">AzureADB2CApp_AppdId</Item>
                        <Item Key="IdTokenAudience">AzureADB2CApp_AppdId</Item>
                        <Item Key="UsePolicyInRedirectUri">false</Item>
                        <Item Key="response_types">code</Item>
                        <Item Key="scope">openid</Item>
                        <Item Key="response_mode">form_post</Item>
                        <Item Key="HttpBinding">POST</Item>
                    </Metadata>
                    <CryptographicKeys>
                        <Key Id="client_secret" StorageReferenceId="B2C_1A_MycompanySecret"/>
                    </CryptographicKeys>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid"/>
                        <OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid"/>
                        <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
                        <OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
                        <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
                    </OutputClaims>
                    <OutputClaimsTransformations>
                        <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
                        <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
                    </OutputClaimsTransformations>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
    </ClaimsProviders>

    <UserJourneys>
        <UserJourney Id="SignUpOrSignInMycompany">
            <OrchestrationSteps>

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

                <!-- Check if the user has selected to sign in using one of the social providers -->
                <OrchestrationStep Order="2" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                            <Value>objectId</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
                        <ClaimsExchange Id="MycompanyExchange" TechnicalProfileReferenceId="MycompanyProfile" />
                    </ClaimsExchanges>
                </OrchestrationStep>

                <!-- Show self-asserted page only if the directory does not have the user account already (i.e. we do not have an objectId). 
          This can only happen when authentication happened using a social IDP. If local account was created or authentication done
          using ESTS in step 2, then an user account must exist in the directory by this time. -->
                <OrchestrationStep Order="3" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                            <Value>objectId</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="SelfAsserted-Social" TechnicalProfileReferenceId="SelfAsserted-Social" />
                    </ClaimsExchanges>
                </OrchestrationStep>

                <!-- This step reads any user attributes that we may not have received when authenticating using ESTS so they can be sent 
          in the token. -->
                <OrchestrationStep Order="4" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                            <Value>authenticationSource</Value>
                            <Value>socialIdpAuthentication</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
                    </ClaimsExchanges>
                </OrchestrationStep>

                <OrchestrationStep Order="5" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

            </OrchestrationSteps>
            <ClientDefinition ReferenceId="DefaultWeb" />
        </UserJourney>
    </UserJourneys>
</TrustFrameworkPolicy>

SignUpOrSigninMycompany.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TrustFrameworkPolicy
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
  PolicySchemaVersion="0.3.0.0"
  TenantId="mytenant.onmicrosoft.com"
  PolicyId="B2C_1A_signup_signin_mycompany"
  PublicPolicyUri="http://mytenant.onmicrosoft.com/B2C_1A_signup_signin_mycompany">

    <BasePolicy>
        <TenantId>mytenant.onmicrosoft.com</TenantId>
        <PolicyId>B2C_1A_TrustFrameworkExtensions</PolicyId>
    </BasePolicy>

    <RelyingParty>
        <DefaultUserJourney ReferenceId="SignUpOrSignInMycompany" />
        <TechnicalProfile Id="PolicyProfile">
            <DisplayName>PolicyProfile</DisplayName>
            <Protocol Name="OpenIdConnect" />
            <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="displayName" />
                <OutputClaim ClaimTypeReferenceId="givenName" />
                <OutputClaim ClaimTypeReferenceId="surname" />
                <OutputClaim ClaimTypeReferenceId="email" />
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/>
                <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
            </OutputClaims>
            <SubjectNamingInfo ClaimType="sub" />
        </TechnicalProfile>
    </RelyingParty>
</TrustFrameworkPolicy>

在 Identity Experience Framework 面板中,我运行 B2C_1A_signup_signin_mycompany 并选择带有https://jwt.ms作为回复 URL 的 testapp1。

标签: azure-active-directoryazure-ad-b2c

解决方案


在 MSDN 上寻求支持后,这没有帮助,我从头开始重做整个过程,虽然我仍然遇到错误,但我克服了这个错误:

AADB2C90037: An error occurred while processing the request. Please contact administrator of the site you are trying to access.

这是由于缺少 objectid 的 outputclaim 引起的。


解决这个问题的原因是我对不清楚的说明(imo)的两个误解。

  • 初学者包策略包含您需要替换的占位符。有些字段看起来像占位符,但不是,我已经替换了它们。
  • 第3 步中给出的声明提供程序包含未在 TrustFrameworkBase.xml 中定义的转换和 OutputClaim。一开始我只是简单地删除了它们,但这次我在 MSDN 上找到了它们的定义并添加了它们。

推荐阅读