【问题标题】:Getting 401 error with UploadSession with Microsoft Graph使用 Microsoft Graph 的 UploadSession 出现 401 错误
【发布时间】:2018-07-09 21:54:56
【问题描述】:

我正在尝试使用守护程序应用将大文件上传到用户的 OneDrive for Business 帐户。我已经成功地进行了身份验证并获得了不记名令牌、创建文件夹并上传了小文件。

对于大文件,我创建了一个上传会话,但在尝试使用该会话添加文件部分时收到错误消息。我已经包含了我的提琴手痕迹来尝试诊断这个。我已删除我的敏感信息。

我请求上传会话

POST https://graph.microsoft.com/v1.0/users/{user id}/drive/items/{folder id}:/Test.csv:/createUploadSession HTTP/1.1
Authorization: Bearer {bearer token}
Content-Type: application/x-www-form-urlencoded
Host: graph.microsoft.com
Content-Length: 0

我收到包含以下内容的回复:

"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#microsoft.graph.uploadSession",
"expirationDateTime":"2016-10-05T11:39:29.5104044Z",
"nextExpectedRanges":["0-"],
"uploadUrl":"https://{my tenant name}.sharepoint.com/personal/name_domain_co_za/_api/v2.0/drive/root:/Backups/Test:/uploadSession?guid='aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'&path='~tmp12_Test.csv'&overwrite=True&rename=False"}

然后我尝试 PUT 到该上传网址

PUT https://{my tenant name}.sharepoint.com/personal/name_domain_co_za/_api/v2.0/drive/root:/Backups/Test:/uploadSession?guid='aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'&path='~tmp12_Test.csv'&overwrite=True&rename=False HTTP/1.1
Authorization: bearer {bearer token}
Content-Range: bytes 0-327679/16333102
Host: {my tenant name}.sharepoint.com
Content-Length: 327680
Expect: 100-continue

然后响应包含以下相关行。

HTTP/1.1 401 Unauthorized
x-ms-diagnostics: 3000006;reason="Token contains invalid signature.";category="invalid_client"

{"error_description":"Invalid issuer or signature."}

我觉得这很奇怪,因为使用当前的应用程序配置,我可以成功地将一个小文件上传到同一路径,所以除非我误解了什么,否则权限应该没有任何问题。

【问题讨论】:

  • github 上有一个针对同一问题的线程。那里有解决方案,我会在这里补充。

标签: office365 daemon onedrive microsoft-graph-api


【解决方案1】:

更新:
实际问题是该请求试图使用仅限应用的令牌通过 Graph 向 OneDrive for Business 进行身份验证。不幸的是,目前不支持这种情况,虽然某些情况可能有效,但也有一些情况不支持(例如这个)。虽然我们无法对时间表发表评论,但它绝对在我们的雷达上!

原文:
通过 Graph 将片段上传到 OneDrive for Business 帐户有几个因素。

  1. 身份验证令牌不兼容。换句话说,您用于在图表上调用 createUploadSession 的不记名令牌不能用于直接命中 OneDrive for Business 端点的 PUT 请求。这主要是因为令牌绑定到特定的受众 - https://graph.microsoft.com/ 的令牌不适用于 https://{my tenant name}.sharepoint.com/

  2. 由于 #1,返回的 uploadUrl 首先实际上不应该需要身份验证 - 我们不希望开发人员为不同的端点处理多个身份验证令牌。

似乎 #2 是您概述的复制中不太正确的地方。您能否确认您收到的uploadUrl 值不包含access_tokenprooftoken 查询参数?如果是这种情况,您能否从createUploadSession 调用的响应中获取request-id 标头?

【讨论】:

  • 如果我没有在 PUT 请求中放置任何不记名令牌,我会得到 403 Forbidden。 uploadUrl 中只有“guid”、“path”、“overwrite”和“rename”查询字符串参数。 createUploadSession 的请求 ID 是 1f7f8c78-ed0d-40ac-9fd0-e6f3c0631989
  • 很抱歉这样跳来跳去,但我找不到那个请求。您是否有提出请求的时间(最好是 UTC) - 这将有助于关联。
  • 感谢您的帮助。我现在又提出了一个要求。 2016 年 10 月 14 日星期五 20:47:45 GMT bdc93a86-84f8-4bed-9d7c-dbd3ce8ba98f
  • 我忽略了您提到您正在编写守护程序应用程序的部分 - 我假设这意味着您正在使用仅限应用程序的令牌?请求信息似乎证实了这一点。不幸的是,Graph 还不支持 OneDrive 场景的此类令牌:(。我会更新我的答案。
  • 非常感谢您帮助诊断此问题。抱歉,我应该更加强调守护进程部分。可惜它还不支持。以后我会继续努力的。
【解决方案2】:

同样的问题:正确上传小文件。

要上传较大的文件,beta 端点“https://graph.microsoft.com/beta”用于实现“上传会话”。此请求成功。

但是当使用这个“上传会话”URI 时,HTTP PUT 命令会失败:

x-ms-diagnostics: 3000006;reason="令牌包含无效签名。";category="invalid_client"

这是发送大文件的 C# 代码:

using (var client = new HttpClient())
{
    byte[] sContents = File.ReadAllBytes(@"<MYLARGEFILE>");
    long length = sContents.Length;
    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessTokenGraphMicrosoft);
    var content = new ByteArrayContent(sContents);
    content.Headers.Add("Content-Length", length.ToString());
    var response = client.PutAsync(<UPLOADSESSIONURI>, content).Result;
}

【讨论】:

  • 感谢您的意见。你想上传到什么? Onedrive/Onedrive for Bus./Sharepoint 文件夹?
  • 嗨达里尔。我以 Onedrive for Business 为目标,与您完全相同,并收到了一个 Sharepoint URI。 :o 我注意到 Office365 实现确实在该目录中创建了一个临时文件。
【解决方案3】:

我在创建上传会话后上传文件时遇到了同样的错误。经过大量的试验错误后,我发现只有当文档名称包含空格时才会得到这个。

原因是 createUploadSession 响应中返回的上传 url 已经进行了 URL 编码。我的 REST 客户端对其进行了双重编码,因为它假定它没有被编码。双重编码后,无法在服务器上找到上传会话,并返回一个空正文的 401。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多