多租户Service Principal访问Azure DevOps Repos权限异常排查
Azure DevOps多租户应用访问问题
单租户流程(正常工作)
- 在Azure门户Entra ID的Tenant_A中创建多租户应用注册,管理员同意链接为:
https://login.microsoftonline.com/common/adminconsent?client_id=<MY_CLIENT_ID> - 拥有Azure DevOps组织OrgInTenant_A,已关联应用所在的Microsoft Entra默认目录
- 通过上述链接完成应用同意,将该应用作为服务主体用户添加到OrgInTenant_A,授予Basic访问权限及项目管理员角色
- 使用NodeJS脚本结合
@azure/identity包,通过应用凭据(租户ID、客户端ID、客户端密钥)获取访问令牌,getToken使用的范围为499b84ac-1321-427f-aa17-267ca6975798/.default - 利用该令牌可获取OrgInTenant_A的项目列表,也能通过git CLI克隆仓库
多租户流程(异常)
- 使用另一微软账号创建Tenant_B,通过步骤1的相同链接完成管理员同意
- 将该服务主体添加到Tenant_B的Azure DevOps组织OrgInTenant_B,配置相同的访问权限,OrgInTenant_B已关联Tenant_B的默认目录
- 使用Tenant_A的应用凭据访问OrgInTenant_B的项目/仓库时,收到错误:
"TF400813: The user '<SOME_UUID>' is not authorized to access this resource."
问题
- Q1:遗漏了哪些步骤?需添加哪些权限/角色,应在何处配置?
- Q2:
<SOME_UUID>代表什么?与现有租户/客户端/密钥ID、Tenant_B中已同意应用的对象ID均不匹配 - Q3:是否可通过Tenant_A的多租户应用凭据访问OrgInTenant_B的项目/仓库?
- Q4:是否与Azure DevOps API仅支持委托权限范围、禁用应用权限范围有关?为何单租户场景正常而多租户异常?
已尝试操作
- 在OrgInTenant_B的设置→安全→策略中启用
第三方应用通过OAuth访问开关 - 在Tenant_B的Azure门户企业应用选项卡中,清除应用类型筛选器后可找到已同意的应用,但无法通过“企业应用”类型筛选到
- 已在Tenant_B的该应用安全权限选项卡中为默认目录授予管理员同意
- 应用所需范围:Azure DevOps的
vso.code_full(代码完全访问权限)、vso.project(项目访问权限)、user_impersonation(用户模拟),以及多个Microsoft Graph测试范围
解答
Q1:遗漏步骤与权限配置
- 指定Tenant_B租户ID获取令牌:当前使用Tenant_A的租户ID请求令牌,导致身份为Tenant_A的服务主体,而非Tenant_B中已同意的服务主体。需在
@azure/identity的认证参数中替换为Tenant_B的租户ID。 - 核对服务主体对象ID:在Tenant_B的Entra ID企业应用中找到该多租户应用对应的服务主体,复制其对象ID,确保OrgInTenant_B中添加的服务主体用户是此ID,而非Tenant_A中的服务主体ID。
- 确认Tenant_B的应用权限同意:在Tenant_B的Entra ID中,为该应用授予Azure DevOps的应用权限(对应
499b84ac-1321-427f-aa17-267ca6975798/.default范围),并完成管理员同意操作。
Q2:<SOME_UUID>的含义
该UUID是Tenant_A中应用注册对应的服务主体ID。由于你用Tenant_A的租户ID获取令牌,此时身份属于Tenant_A的服务主体,而该主体未被授权访问OrgInTenant_B,因此Azure DevOps返回此ID并提示未授权。
Q3:跨租户访问的可行性
可以,但必须满足两个核心条件:
- 获取令牌时指定Tenant_B的租户ID,让Entra ID颁发Tenant_B中该应用对应的服务主体令牌。
- Tenant_B已完成该应用的管理员同意,且对应的服务主体已被添加到OrgInTenant_B并授予相应访问权限。
Q4:权限范围与单/多租户差异
Azure DevOps API优先支持委托权限,但应用权限(/.default范围)在单租户场景可正常工作,原因是服务主体与Azure DevOps组织同属一个Entra租户,权限验证逻辑直接关联。而多租户场景下,若仍使用Tenant_A的租户ID获取令牌,服务主体身份不属于Tenant_B的Entra目录,Azure DevOps无法识别其授权关系,因此报错。
解决核心是切换为Tenant_B的租户ID获取令牌,确保使用的是Tenant_B中已同意的服务主体身份,此时应用权限或委托权限均可生效(委托权限需结合用户上下文,应用权限仅需服务主体授权)。
内容的提问来源于stack exchange,提问作者Oleksiy Kachynskyy
相关产品推荐
相关产品推荐

