我目前正在开发一个 Microsoft Teams 机器人,该机器人旨在将文件上传到 OneDrive,以便根据聊天请求与用户共享 URL。但是,我经常遇到错误消息“scp 或角色声明需要出现在令牌中。”的问题。
以下是我正在做的事情和已采取的步骤的详细说明:
第 1 步:初始身份验证请求
我使用以下 POST 请求启动身份验证过程:
POST /<MY TENANT ID>/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Authorization: Bearer <MY ACCESS TOKEN>
grant_type=client_credentials&client_id=<MY APP ID>&client_secret=<MY APP PASSWORD>&resource=https%3A%2F%2Fgraph.microsoft.com
这成功返回了一个不记名访问令牌,我用它来进行进一步的交互。
第2步:文件上传请求
有了访问令牌,我继续上传一个仅包含内容“Hello world”的纯文本文件。这是我正在使用的 POST 请求:
POST /v1.0/drive/root:/filename.txt:/content HTTP/1.1
Host: graph.microsoft.com
Authorization: Bearer <MY ACCESS TOKEN>
Content-Type: text/plain
hello_world
然而,我得到的回应是:
{"error": {"code": "AccessDenied", "message": "Either scp or roles claim need to be present in the token.", "innerError": {"date": "2023-08-11T20:51:52", "request-id": "e7bb0afc-d6ce-348e-b6cf-7cba046e70b4", "client-request-id": "e7bb0afc-d6ce-4f07-b6cf-7cba046e7222"}}}
我的问题是:
如果您错过在应用程序注册中添加所需的 API 权限或错过授予其管理员同意,通常会发生该错误。
我注册了一个 Azure AD 应用程序,并通过添加同意添加了 Application
类型的
Files.ReadWrite.All
权限:
现在,我通过 Postman 使用客户端凭据流生成了 访问令牌,参数如下:
POST https://login.microsoftonline.com/tenantID/oauth2/v2.0/token
grant_type:client_credentials
client_id: appID
client_secret: secret
scope: https://graph.microsoft.com/.default
回复:
要检查令牌是否具有权限,您可以通过将令牌粘贴到jwt.ms中进行解码,并在其中找到
roles
声明:
现在,使用下面的 PUT 请求上传一个仅包含内容“Hello world”的纯文本文件,方法是在其中包含
userID
:
PUT https://graph.microsoft.com/v1.0/users/<userID>/drive/root:/srifile.txt:/content
Authorization: Bearer <MY ACCESS TOKEN>
Content-Type: text/plain
hello_world
回复:
为了确认,我在用户的 OneDrive 中检查了相同的内容,其中文件创建成功,如下所示:
当我打开上面的文本文件时,里面有
hello_world
: