多租户Azure AD对接Azure AD B2C时如何在颁发令牌中包含roles
我已参照官方文档完成配置:在Azure Active Directory B2C中使用自定义策略配置多租户Azure Active Directory登录,各Azure AD租户的管理员可独立管理自身租户下的用户。当前登录功能运行正常,现需要实现应用角色(app roles)支持。
我已在Azure AD B2C应用的应用程序清单(application manifest)中定义了app roles,且这些角色可在各关联Azure AD租户中正常选择分配。但目前用户登录后获取的令牌中并未包含roles声明。查阅文档得知roles声明默认不会包含在Azure AD B2C颁发的令牌中,需要可行方案将roles声明加入颁发的令牌。
相关配置截图:
- 应用清单中的角色定义:

- Azure AD租户中角色分配界面:


问题核心原因是:你在多租户Azure AD应用上配置分配的roles声明,是由作为身份提供方(IdP)的各Azure AD租户返回给B2C的,Azure AD B2C默认不会透传IdP返回的自定义/非默认声明到最终颁发给应用的令牌中,需要通过修改自定义策略完成声明映射和输出,步骤如下:
1. 前置校验:确认Azure AD IdP已返回roles声明
首先确认你配置的多租户Azure AD身份提供方确实会返回roles声明:
- 检查你在B2C中配置AAD IdP时请求的权限范围,必须包含你用于多租户登录的AAD应用注册对应的客户端ID/应用ID URI,即scope配置需要包含
openid profile offline_access <你的多租户AAD应用Client ID>,只有请求了对应应用的授权范围,AAD才会在返回的令牌中携带该应用分配的roles声明。 - 可以临时在策略中加日志或者抓取AAD返回给B2C的id_token,通过jwt解析工具确认payload中是否存在
roles数组,如果不存在先排查AAD侧的角色分配、scope配置问题。
2. 在自定义策略中声明roles声明类型
打开你的自定义策略基础扩展文件(通常是TrustFrameworkExtensions.xml),在<BuildingBlocks>节点下的<ClaimsSchema>中添加roles的声明定义:
<ClaimType Id="roles"> <DisplayName>Application Roles</DisplayName> <DataType>stringCollection</DataType> </ClaimType>
注意:必须将数据类型设置为stringCollection,否则多角色场景下只会返回最后一个分配的角色值。
3. 配置AAD IdP的输出声明映射
在同一个扩展文件中,找到你配置多租户Azure AD登录的<ClaimsProvider>节点,在其对应的OIDC/OAuth2技术配置文件的<OutputClaims>节点下添加声明映射,将AAD返回的roles声明存入B2C声明包:
<OutputClaim ClaimTypeReferenceId="roles" PartnerClaimType="roles" />
4. 在信赖方策略中输出roles声明
打开你的登录注册信赖方策略文件(通常是SignUpOrSignIn.xml这类以_RelyingParty结尾的策略文件),在其技术配置文件的<OutputClaims>节点下添加roles声明,让B2C将该声明写入最终颁发给应用的id_token和access_token中:
<OutputClaim ClaimTypeReferenceId="roles" />
配置完成后重新上传策略,测试登录即可在返回的令牌中看到roles声明。
常见踩坑说明
- 不要混淆B2C应用注册和多租户AAD应用注册的角色配置:你当前场景下分配给各租户用户的角色,是配置在你用于多租户登录的AAD多租户应用注册上的,不是配置在B2C租户下的应用注册上的,两者的app roles完全独立。
- 如果你同时需要支持B2C本地账号的角色分配,需要额外配置本地账号的角色声明逻辑,并且和AAD IdP返回的roles声明做合并,否则本地账号登录时roles声明为空。
- 如果你当前使用的是B2C用户流(User Flow)而非自定义策略,没有直接透传IdP自定义声明的能力,必须切换到自定义策略才能实现该需求。
内容的提问来源于stack exchange,提问作者Martin4ndersen

