如何通过Azure CLI为Azure托管标识分配Graph的Directory.Read.All权限?
你遇到的错误核心原因是用错了权限配置体系——az role assignment是针对Azure RBAC(资源基于角色的访问控制)的命令,用于管控对Azure云资源(比如VM、存储账户)的访问;而Microsoft Graph的Directory.Read.All属于Azure AD应用权限,是专门针对Azure AD生态API的权限系统,二者完全不兼容,所以才会提示“没有有效的租户级资源提供者”。
下面是用Azure CLI完成托管标识配置Microsoft Graph Directory.Read.All应用权限的正确步骤:
步骤1:获取必要的ID参数
首先我们需要三个关键ID:Microsoft Graph服务主体的Object ID、目标权限的ID,以及你已经持有的托管标识Object ID(fa22d971-c442-41f2-add1-77e636f80d31)。
执行以下命令获取前两个ID:
# 获取Microsoft Graph服务主体的Object ID graph_sp_object_id=$(az ad sp list --filter "appId eq '00000003-0000-0000-c000-000000000000'" --query "[0].objectId" -o tsv) # 获取Directory.Read.All应用权限的ID(仅筛选允许应用类型的权限) directory_read_all_permission_id=$(az ad sp list --filter "appId eq '00000003-0000-0000-c000-000000000000'" --query "[0].appRoles[?value=='Directory.Read.All' && allowedMemberTypes contains 'Application'].id" -o tsv) # 你的托管标识Object ID(已提供) msi_object_id="fa22d971-c442-41f2-add1-77e636f80d31"
步骤2:给托管标识添加应用权限
使用az ad sp permission add命令将权限关联到托管标识的服务主体上:
az ad sp permission add \ --id $msi_object_id \ --api $graph_sp_object_id \ --api-permissions $directory_read_all_permission_id=Role
这里的=Role表示我们要添加的是应用权限(对应Microsoft Graph的appRoles),而非面向用户的委托权限(Scope)。
步骤3:授予管理员同意
应用权限必须经过全局管理员或目录管理员的同意才能生效,执行以下命令完成授权:
az ad sp permission grant \ --id $msi_object_id \ --api $graph_sp_object_id \ --permission-id $directory_read_all_permission_id
如果你需要批量同意该托管标识已添加的所有Microsoft Graph权限,也可以用--scope "https://graph.microsoft.com/.default"参数替代--permission-id。
验证权限是否配置成功
执行以下命令查看托管标识已分配的Microsoft Graph权限:
az ad sp permission list --id $msi_object_id --api $graph_sp_object_id
输出中应该能看到Directory.Read.All权限,且consentType字段为AllPrincipals,表示已完成管理员同意。
关键注意事项
- 执行这些命令需要拥有全局管理员、目录管理员或应用程序管理员角色的账号权限;
- 托管标识(无论系统分配还是用户分配)本质是Azure AD中的服务主体,所以我们操作的是它的服务主体对象;
- 务必区分Azure RBAC和Azure AD应用权限:前者管控Azure云资源访问,后者管控Azure AD生态API(如Microsoft Graph)的访问。
内容的提问来源于stack exchange,提问作者Peter Lasne

