使用Microsoft Graph调用接口报错:令牌需包含scp或roles声明
解决Microsoft Graph API调用时"Either scp or roles claim need to be present in the token"错误
我来帮你拆解这个问题——你遇到的这个错误,核心原因确实和你排查的一样:你的访问令牌里缺少了权限声明(scp或roles字段),这通常和你获取令牌的流程、权限配置的细节有关。咱们一步步来解决:
先搞懂两个关键权限字段
scp字段:对应委派权限,也就是以当前登录用户的身份调用API,Graph Explorer就是用这种模式(因为你手动登录了账号)。roles字段:对应应用权限,也就是以应用本身的身份调用API,不需要用户登录,适合后台服务场景。
你的场景是用户登录状态下操作OneNote,所以应该用委派权限,目标是让令牌里出现scp字段。
排查步骤 & 解决方案
1. 检查获取令牌时的scope参数是否正确
你在调用https://login.microsoftonline.com/common/oauth2/v2.0/token时,必须在scope参数里明确指定需要的Graph权限,比如OneNote和SharePoint相关的权限:
scope=Notes.ReadWrite.All Sites.Read.All
- 权限名称要和Azure AD里配置的一致,多个权限用空格分隔。
- 如果
scope参数为空或者没有包含任何Graph权限,令牌里自然不会生成scp字段,这是最常见的原因。
2. 确认权限已经完成同意流程
即使你在Azure AD的应用注册里配置了委派权限,也需要完成权限同意:
- 如果是个人账号/非管理员账号:在authorization code flow的授权环节(用户跳转到微软登录页时),需要勾选同意你申请的权限。
- 如果是企业租户:需要管理员在Azure AD应用注册的「权限」页面,点击「授予管理员同意」(针对所有用户),或者用户自己在授权时同意(如果权限允许用户自行同意)。
- 没有完成同意的话,哪怕配置了权限,令牌里也不会包含
scp声明。
3. 验证令牌的受众和权限声明
拿到令牌后,解码查看以下两个关键点:
aud字段:必须是https://graph.microsoft.com,如果受众不对,Graph API会拒绝验证。scp字段:应该包含你申请的权限(比如Notes.ReadWrite.All),如果没有,说明权限同意或scope参数有问题。
4. 检查授权流程的一致性
确保你获取code时的scope,和获取token时的scope是一致的(或者是子集):
- 比如你在跳转到微软授权页时,请求的
scope是Notes.Read,那后续获取token时的scope不能超出这个范围,否则超出的权限会被忽略,导致scp字段缺失。
举个正确的token请求示例
假设你需要读写OneNote页面和读取SharePoint站点,token请求的参数应该像这样:
grant_type=authorization_code client_id=你的客户端ID client_secret=你的客户端密钥 code=用户授权后拿到的授权码 redirect_uri=和授权时完全一致的重定向URI scope=Notes.ReadWrite.All Sites.Read.All
按照这个流程走,你拿到的令牌里应该会出现scp字段,再调用https://graph.microsoft.com/v1.0/sites或者OneNote相关接口就不会报错了。
内容的提问来源于stack exchange,提问作者user3665749
相关产品推荐
相关产品推荐

