Python调用Az CLI获取用户Azure AD组信息报权限不足如何解决
问题原因
认证成功仅代表托管标识的身份校验通过,不代表其拥有执行对应操作的权限。az ad user get-member-groups 底层调用Microsoft Graph接口查询Entra ID(原Azure AD)目录数据,这类操作的权限不属于Azure资源RBAC管控范畴,必须单独给托管标识分配Entra ID侧的Microsoft Graph权限,否则必然返回Insufficient privileges to complete the operation错误。
排查解决步骤
- 第一步:为系统分配托管标识配置正确的Graph权限
- 进入Azure函数的「标识」页面,复制系统分配托管标识对应的对象(主体)ID。
- 在Entra ID管理页找到该托管标识对应的服务主体,为其分配以下Microsoft Graph应用权限(注意不要选委托权限,托管标识作为服务主体认证时仅识别应用权限):
User.Read.All:允许读取所有用户的目录基础信息GroupMember.Read.All:允许读取组的成员关系数据
- 权限分配完成后,点击「授予租户管理员同意」,应用权限必须经过管理员同意才会生效。
注意:不要尝试给托管标识分配订阅/资源组层面的Azure RBAC角色(如读者、参与者),这类角色仅对Azure资源管控操作生效,对Entra ID目录查询完全无效。
- 第二步:修正代码与运行环境问题
- 你代码中初始化的
DefaultAzureCredential对象没有被后续CLI调用逻辑使用,属于冗余代码,可以直接删除。 - 确认函数运行环境中的Azure CLI版本不低于2.37.0:低于该版本的az ad命令默认调用已退役的Azure AD Graph端点,哪怕配置了Microsoft Graph权限也会报错。
- 参考修正后的可运行代码:
import logging import azure.functions as func from azure.cli.core import get_default_cli def main(req: func.HttpRequest) -> func.HttpResponse: cli = get_default_cli() # 使用系统分配托管标识完成CLI登录 login_code = cli.invoke(['login', '--identity', '--allow-no-subscriptions']) if login_code != 0: logging.error(f"CLI登录失败: {cli.result.error}") return func.HttpResponse("认证失败", status_code=500) # 执行用户所属组查询 query_code = cli.invoke([ 'ad', 'user', 'get-member-groups', '--id', 'someid@somedomain.com', '--output', 'json' ]) if query_code == 0: logging.info(f"用户所属组列表: {cli.result.result}") return func.HttpResponse(str(cli.result.result)) else: logging.error(f"组查询失败: {cli.result.error}") return func.HttpResponse("查询失败", status_code=500) - 你代码中初始化的
- 第三步:生效验证
权限配置完成后等待1-2分钟让权限同步,再触发函数测试。如果仍报错,可在函数中执行az ad sp show --id <你的托管标识客户端ID>,确认当前CLI登录的主体确实是你刚才配置权限的托管标识,排除身份错配问题。
如果查询的目标用户属于其他租户或Azure AD B2C租户,还需要额外确认跨租户访问策略、B2C租户的Graph权限配置是否符合要求。
常见踩坑
- 误给托管标识分配委托权限:这类权限需要用户上下文,托管标识的非交互式认证场景下无法生效。
- 分配权限后未执行管理员同意:未同意的应用权限处于未激活状态,调用接口时仍会判定无权限。
- CLI版本过旧:旧版本CLI调用已废弃的AAD Graph端点,微软已经完全关停该端点的访问,所有调用都会返回权限错误。
内容的提问来源于stack exchange,提问作者ByteCruncher
相关产品推荐
相关产品推荐

