Azure B2C:为本地登录添加输出声明的配置问题
解决Azure AD B2C本地用户返回
email和emails声明的问题 问题分析
当前配置的核心问题在于声明转换的时机和位置错误:你将InputClaimsTransformation放在了RelayingParty的PolicyProfile中,但本地用户的signInNames.emailAddress声明是在本地登录技术流程中才获取到的,此时执行转换可能无法拿到有效数据。另外,默认B2C策略中可能未定义otherMails集合类型声明,且重复映射email声明会导致冲突。
分步解决方案
1. 定义otherMails集合类型声明
在TrustFrameworkExtensions.xml的<ClaimsSchema>节点中添加集合类型声明(如果已有可跳过):
<ClaimsSchema> <ClaimType Id="otherMails"> <DisplayName>其他邮箱地址</DisplayName> <DataType>stringCollection</DataType> <AdminHelpText>存储用户关联的其他邮箱地址集合</AdminHelpText> </ClaimType> </ClaimsSchema>
2. 优化声明转换逻辑
替换原有的AddItemToStringCollection转换为更直接的CreateStringCollectionFromClaim,将单个邮箱字符串转为集合:
<BuildingBlocks> <ClaimsTransformations> <ClaimsTransformation Id="CreateOtherMailsFromSignInEmail" TransformationMethod="CreateStringCollectionFromClaim"> <InputClaims> <InputClaim ClaimTypeReferenceId="signInNames.emailAddress" TransformationClaimType="inputClaim" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="otherMails" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation> </ClaimsTransformations> </BuildingBlocks>
3. 将转换绑定到本地登录技术流程
找到TrustFrameworkExtensions.xml中本地登录的技术配置(通常是LocalAccountSignInWithEmailUsername),在其<OutputClaimsTransformations>中添加转换,确保登录完成后立即生成otherMails声明:
<TechnicalProfile Id="LocalAccountSignInWithEmailUsername"> <!-- 保留原有配置 --> <OutputClaimsTransformations> <OutputClaimsTransformation ReferenceId="CreateOtherMailsFromSignInEmail" /> </OutputClaimsTransformations> </TechnicalProfile>
4. 修正RelayingParty的输出声明
移除重复的email映射,确保email和emails声明正确输出:
<RelyingParty> <DefaultUserJourney ReferenceId="CustomSignUpOrSignIn" /> <Endpoints> <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="signInNames.emailAddress" PartnerClaimType="email" /> <OutputClaim ClaimTypeReferenceId="otherMails" PartnerClaimType="emails" /> <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/> <OutputClaim ClaimTypeReferenceId="identityProvider" /> <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" /> </OutputClaims> <SubjectNamingInfo ClaimType="sub" /> </TechnicalProfile> </RelyingParty>
关键说明
- 声明转换必须放在本地登录技术流程的输出阶段,确保
signInNames.emailAddress已被正确获取后再执行转换。 - 使用
CreateStringCollectionFromClaim可以直接将单个字符串转为集合,避免AddItemToStringCollection需要预先存在集合的限制。 - 移除重复的
email映射,避免OIDC响应中出现重复声明导致的异常。
内容的提问来源于stack exchange,提问作者Alex S
相关产品推荐
相关产品推荐

