使用Client Credentials Grant Flow获取令牌调用OneDrive接口遇权限错误求助
解决Client Credentials流调用OneDrive上传会话接口的AccessDenied错误
我来帮你排查这个问题,你遇到的AccessDenied错误提示"Either scp or roles claim need to be present in the token",核心原因是你拿到的访问令牌里没有包含Graph API认可的权限声明——哪怕你给应用加了管理员权限,也大概率是配置环节有疏漏,下面是具体的排查和解决步骤:
1. 确认应用权限的类型与授予状态
Client Credentials流属于应用级权限,不是用户委派权限,所以你需要:
- 登录Azure AD门户,找到你的应用,进入「API权限」页面
- 确保添加的是应用权限(不是委派权限),比如针对OneDrive/Graph API的
Files.ReadWrite.All或Sites.ReadWrite.All(这两个权限足够支持创建上传会话) - 关键步骤:添加权限后,必须点击页面上的**「授予管理员同意」**按钮,只有完成这一步,权限才会生效,令牌里才会生成
roles声明
2. 检查获取令牌时的Scope参数
Client Credentials流的scope格式是固定的,不能用委派权限的scope:
- 正确的scope应该是:
https://graph.microsoft.com/.default - 如果你用了其他scope(比如
user.read这类委派权限的scope),令牌里只会生成scp字段(但应用流不需要这个),甚至可能缺少权限声明,导致API拒绝
你可以把拿到的令牌复制到JWT解析工具(建议用本地离线工具,避免敏感信息泄露)里查看payload:
- 如果是正确的应用权限令牌,payload里会有
roles字段,值是你授予的权限(比如["Files.ReadWrite.All"]) - 如果没有
roles字段,说明权限授予或scope参数有问题
3. 验证API调用的权限匹配
/v1.0/users/{userId}/drive/items/{itemId}/createUploadSession这个接口需要的应用权限是Files.ReadWrite.All或Sites.ReadWrite.All,要确保你给应用添加的是这两个权限之一,并且已经完成管理员同意
4. 排查其他常见疏漏
- 确认你在Postman/代码里使用的
client_id和Azure AD里配置的应用ID一致,别选错了应用 - 检查令牌的
aud(受众)字段是否为https://graph.microsoft.com,如果受众不对,Graph API会直接拒绝请求
举个Postman获取正确令牌的示例
- 请求方法:POST
- 请求URL:
https://login.microsoftonline.com/{你的租户ID}/oauth2/v2.0/token - 请求体(form-data格式):
client_id: 你的应用注册IDclient_secret: 你的应用客户端密钥grant_type:client_credentialsscope:https://graph.microsoft.com/.default
按照上面的步骤排查,应该就能解决令牌缺少权限声明的问题,顺利调用创建上传会话的接口了。
内容的提问来源于stack exchange,提问作者Jayendra Kambli
相关产品推荐
相关产品推荐

