Azure B2C自定义策略集成AAD报错AADB2C90037求解决
我查阅了多个涉及该错误的问题、GitHub帖子及微软反馈,还与支持工程师沟通了一小时,仍未找到问题所在。
我基于入门包和配置工具,为Asp.Net 5.0 Web应用配置了自定义策略以允许本地账户访问。本地用户可通过邮箱和密码正常登录,使用自定义策略是因为需要支持本地用户修改(而非重置)密码。
同时我配置了Azure AD目录的联合登录(此前操作过多次),但此次常规配置出现问题:测试Azure AD登录时,流程看似完成,却弹出模糊错误:
AADB2C90037: An error occurred while processing the request. Please contact administrator of the site you are trying to access.
Correlation ID: {etc}
我的ClaimsProvider配置如下:
<ClaimsProvider> <Domain>REDACTED</Domain> <DisplayName>Sign in with your REDACTED account</DisplayName> <TechnicalProfiles> <TechnicalProfile Id="AADREDACTED-OpenIdConnect"> <DisplayName>REDACTED Email Holder</DisplayName> <Description>Sign in with your REDACTED email</Description> <Protocol Name="OpenIdConnect"/> <Metadata> <Item Key="METAREDACTED">https://login.microsoftonline.com/REDACTED/v2.0/.well-known/openid-configuration</Item> <Item Key="client_id">REDACTED</Item> <Item Key="response_types">code</Item> <Item Key="scope">openid</Item> <Item Key="response_mode">form_post</Item> <Item Key="HttpBinding">POST</Item> <Item Key="UsePolicyInRedirectUri">false</Item> </Metadata> <CryptographicKeys> <Key Id="client_secret" StorageReferenceId="B2C_1A_REDACTEDAppSecret"/> </CryptographicKeys> <OutputClaims> <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="sub"/> <OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid"/> <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" /> <OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" /> <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" /> <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" /> <OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" /> </OutputClaims> <OutputClaimsTransformations> <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/> <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/> <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/> <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/> </OutputClaimsTransformations> <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin"/> </TechnicalProfile> </TechnicalProfiles> </ClaimsProvider>
User Journey配置:
<UserJourney Id="SignInWithREDACTED"> <OrchestrationSteps> <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin"> <ClaimsProviderSelections> <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" /> <ClaimsProviderSelection TargetClaimsExchangeId="AzureADREDACTEDExchange" /> </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="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" /> <ClaimsExchange Id="AzureADREDACTEDExchange" TechnicalProfileReferenceId="AADREDACTED-OpenIdConnect" /> </ClaimsExchanges> </OrchestrationStep> <!-- This step reads any user attributes that we may not have received when in the token. --> <OrchestrationStep Order="3" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" /> </OrchestrationSteps> <ClientDefinition ReferenceId="DefaultWeb" /> </UserJourney>
RelyingParty配置:
<RelyingParty> <DefaultUserJourney ReferenceId="SignInWithREDACTED" /> <Endpoints> <!--points to refresh token journey when app makes refresh token request--> <Endpoint Id="Token" UserJourneyReferenceId="RedeemRefreshToken" /> </Endpoints> <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>
所有配置中的TenantId均已更新,我遗漏了什么?
更新
通过Application Insights追踪到的底层错误:
A claim could not be found for lookup claim with id "objectId"
defined in technical profile with id "AAD-UserReadUsingObjectId"
policy "B2C_1A_signup_signin" of tenant "REDACTED.onmicrosoft.com
这个错误的核心原因是:用户通过Azure AD联合登录时,流程走到第3步调用AAD-UserReadUsingObjectId技术profile时,objectId声明不存在。本地账户登录时objectId会在登录/注册步骤生成,但联合登录流程中,当前配置未在用户首次登录(创建B2C用户记录)时生成并传递objectId到后续步骤。
修复步骤如下:
修改用户旅程第3步的前置条件
在调用AAD-UserReadUsingObjectId前添加前置条件:仅当objectId存在时才执行该步骤。联合登录首次登录时,用户记录刚创建,objectId尚未被读取;而本地账户登录时objectId已存在,可正常执行读取操作。修改后的第3步代码:<OrchestrationStep Order="3" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimsExist" ExecuteActionsIf="false"> <Value>objectId</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep>确认联合登录技术profile的用户创建逻辑
检查AADREDACTED-OpenIdConnect技术profile是否关联了正确的会话管理配置,确保首次登录时自动触发B2C用户记录创建,从而生成objectId。可确认是否包含以下配置:<UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />验证声明传递
启用Application Insights详细日志,查看每个步骤的声明传递情况,确认objectId是否在第2步联合登录完成后被正确生成并加入声明包。
内容的提问来源于stack exchange,提问作者Jude Fisher

