为何访问Google Workspace Admin SDK时出现403权限不足错误?
问题:Admin SDK Directory API 返回403权限范围不足错误
调用Admin SDK用户列表API时触发403 Forbidden错误,附加API Key后问题依然存在:
请求详情
XHRGET https://admin.googleapis.com/admin/directory/v1/users?customer=some_custumer [HTTP/3 403 Forbidden 220ms]
错误响应
{ "error": { "code": 403, "message": "Request had insufficient authentication scopes.", "errors": [ { "message": "Insufficient Permission", "domain": "global", "reason": "insufficientPermissions" } ], "status": "PERMISSION_DENIED", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT", "domain": "googleapis.com", "metadata": { "method": "ccc.hosted.frontend.directory.v1.DirectoryUsers.List", "service": "admin.googleapis.com" } } ] } }
响应头提示的所需范围
www-authenticate: Bearer realm="https://accounts.google.com/", error="insufficient_scope", scope="https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/directory.user https://www.googleapis.com/auth/admin.directory.user.readonly https://www.googleapis.com/auth/apps.directory.user.readonly https://www.googleapis.com/auth/directory.user.readonly https://www.googleapis.com/auth/cloud-platform"
已完成配置
- Google Console中已配置应用的认证及权限范围
- Admin Console中已配置全域委派
- OAuth认证流程正常,可获取AccessToken
期望目标
通过API列出所有Google Workspace用户
解决方案
校验AccessToken的实际权限范围:
使用token信息接口检查当前AccessToken包含的范围,确认是否包含https://www.googleapis.com/auth/admin.directory.user.readonly(只读需求)或https://www.googleapis.com/auth/admin.directory.user(读写需求)。若未包含,说明生成token时未正确携带配置的权限范围。确保全域委派范围精确匹配:
在Admin Console的全域委派设置中,必须添加完全一致的权限范围字符串,不能存在拼写错误、前缀缺失或路径修改(例如必须完整填写https://www.googleapis.com/auth/admin.directory.user.readonly)。移除API Key参数:
Admin SDK Directory API属于Google Workspace专属API,API Key无法用于身份验证,必须使用OAuth 2.0 AccessToken(用户授权或服务账号模拟的token),请求中附加&key=参数完全无效,直接移除即可。验证服务账号授权(若使用服务账号):
- 确认服务账号已在Admin Console中完成全域委派配置
- 确保服务账号模拟的用户(或自身)拥有Google Workspace管理员权限,至少具备查看用户列表的权限
- 检查服务账号是否已添加至Workspace的API授权列表
重新生成AccessToken:
若当前使用的AccessToken是在修改权限范围之前生成的,旧token不会自动继承新配置的范围,需重新发起OAuth流程获取新的AccessToken。
内容的提问来源于stack exchange,提问作者Moises B. Almeida

