Azure B2C自定义流SSO后无法获取外部租户用户标识信息
Azure B2C 外部租户SSO后无法获取外部用户标识声明问题
问题背景
- 现有应用基于Azure B2C实现登录并调用API,通过SUSI用户流能正常获取本地租户的登录名、邮箱等声明
- 已配置其他微软租户及未来Google的SSO,上传了TrustFrameworkBase、Localization、Extension和SignUpOrSignIn XML文件,登录流程能正常显示Microsoft登录选项并完成登录
- 核心问题:传递给API的JWT仅包含本地租户信息,缺少外部租户ID、外部用户ID、用户邮箱/登录名,没法关联本地数据库记录
当前JWT响应示例
{ "alg": "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256", "kid": "##l5oIPM31fXvTQA6jSNJJfFifuIxVl7xvJf5UHuPxY", "typ": "JWT" }.{ "ver": "1.0", "iss": "https://####.b2clogin.com/##cbc16c-147c-4662-b581-933476086d57/v2.0/", "sub": "##f120af-77f2-49f4-8d28-2cc4bdcd25f7", "aud": "##50964c-2cbf-4cfa-966c-030e72c3be81", "exp": 1694428197, "acr": "b2c_1a_signup_signin", "nonce": "defaultNonce", "iat": 1694424597, "auth_time": 1694424597, "name": "Mike", "family_name": "C", "tid": "##cbc16c-147c-4662-b581-933476086d57", "nbf": 1694424597 }.[Signature]
当前OutputClaims配置
<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>
解决方案
要拿到外部身份提供商的标识信息,得从外部IDP的技术配置文件映射声明、策略输出声明这两个核心环节调整:
1. 在Extension.xml中声明外部IDP的专属声明类型
先定义要获取的外部租户ID、外部用户ID这两个声明类型:
<BuildingBlocks> <ClaimsSchema> <ClaimType Id="externalTenantId"> <DisplayName>External Tenant ID</DisplayName> <DataType>string</DataType> </ClaimType> <ClaimType Id="externalUserId"> <DisplayName>External User ID</DisplayName> <DataType>string</DataType> </ClaimType> </ClaimsSchema> </BuildingBlocks>
2. 修改Microsoft IDP技术配置文件的声明映射
在Extension.xml里找到Microsoft Account对应的技术配置文件(通常ID是MSA-OIDC),添加外部IDP原生声明的映射:
<TechnicalProfiles> <TechnicalProfile Id="MSA-OIDC"> <DisplayName>Microsoft Account</DisplayName> <Protocol Name="OpenIdConnect"/> <Metadata> <!-- 保留原有元数据配置 --> </Metadata> <OutputClaims> <!-- 保留原有输出声明 --> <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email"/> <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name"/> <OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="family_name"/> <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name"/> <!-- 新增外部租户ID、用户ID的映射 --> <OutputClaim ClaimTypeReferenceId="externalTenantId" PartnerClaimType="tid"/> <OutputClaim ClaimTypeReferenceId="externalUserId" PartnerClaimType="oid"/> </OutputClaims> </TechnicalProfile> </TechnicalProfiles>
3. 在SignUpOrSignIn策略中输出外部声明
修改你当前的OutputClaims配置,把外部标识声明加进去:
<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}" /> <!-- 新增外部标识声明输出 --> <OutputClaim ClaimTypeReferenceId="externalTenantId" /> <OutputClaim ClaimTypeReferenceId="externalUserId" /> </OutputClaims>
4. 可选:持久化外部声明到B2C用户数据库
如果需要把外部标识信息存在B2C的用户存储里,在Extension.xml的AAD-UserWriteUsingAlternativeSecurityId技术配置文件中添加持久化声明:
<TechnicalProfile Id="AAD-UserWriteUsingAlternativeSecurityId"> <PersistedClaims> <!-- 保留原有持久化声明 --> <PersistedClaim ClaimTypeReferenceId="email"/> <!-- 新增外部声明持久化 --> <PersistedClaim ClaimTypeReferenceId="externalTenantId"/> <PersistedClaim ClaimTypeReferenceId="externalUserId"/> </PersistedClaims> </TechnicalProfile>
5. 未来Google SSO的适配提示
当添加Google身份提供商时,对应映射的声明是:
- 外部用户ID对应Google返回的
sub声明 - 邮箱对应
email声明
同样需要在Google的技术配置文件中添加OutputClaims映射,并在SignUpOrSignIn策略中输出这些声明。
验证
修改后重新上传策略,登录后查看JWT,应该会包含externalTenantId、externalUserId、email等字段,用这些信息就能关联本地数据库的用户记录了。
内容的提问来源于stack exchange,提问作者Mike C
相关产品推荐
相关产品推荐

