首页 > 解决方案 > SharePoint Online 多租户 REST 调用对肯定存在的资源返回 404

问题描述

我正在尝试访问 SharePoint Online REST API(这是手动编码的 REST 调用,没有使用任何库)。

使用授权授予流程获取访问令牌,如下所示:

  1. 我发送浏览器https://login.microsoftonline.com/common/oauth2/authorize? ...

  2. 这重定向到我们从中提取访问代码的处理程序端点

  3. 我通过以下方式获取租户 ID: GET https://{tenantname}.sharepoint.com/_vti_bin/client.svc 然后从 WWW-Authenticate 标头中提取租户 ID

  4. 然后我发布https://login.microsoftonline.com/{tenantid}/oauth2/authorize以获取访问令牌

当我使用该访问令牌时,我可以使用以下方式进行查询:GET https://{tenantname}.sharepoint.com/_api/search/query?querytext=....

这有效并返回文件。

但是当我尝试检索有关其中一个文档的信息时: GET https://{tenantname}.sharepoint.com/_api/web/getfilebyserverrelativeurl('/TestFiles/test.pdf')

我收到带有以下正文的 404 响应:

{"odata.error":{"code":"-2130575338, Microsoft.SharePoint.SPException","message":{"lang":"en-US","value":"文件 /TestFiles/test. pdf 不存在。"}}}

如果我在浏览器中导航到 URL (https://{tenantname}.sharepoint.com/TestFiles/test.pdf),它会毫无问题地访问该文件。

这让我觉得我遇到了某种权限问题。

我尝试在授权重定向中设置以下范围:

尝试 1:范围 = Web.Write AllSites.Write Site.Write 尝试 2:范围 = https://{tenantname}.sharepoint.com/.default 尝试 3:范围 = https://{tenantname}.sharepoint.com/ Web.Write https://{tenantname}.sharepoint.com/AllSites.Write https://{tenantname}.sharepoint.com/Site.Write

无论我设置什么作为授权 URL 的范围参数,访问令牌的 JWT 详细信息都会显示(如果有人需要,我可以发布整个解码的 JWT):

"scp": "用户.Read"

我所做的任何事情都不会对令牌中的 scp 产生任何影响——我不知道这是否是问题所在。如果是这样,我会很高兴听到如何正确请求范围。

Azure Active Directory 中的应用程序注册具有所需的权限(以及更多权限):

在此处输入图像描述

我究竟做错了什么?


更新:切换到 OAuth 端点 v2.0:

https://login.microsoftonline.com/common/oauth2/v2.0/authorize

使用查询参数: response_type = code client_id = my app id redirect_uri = my redirect uri scope = <variing - 我将在下面解释不同场景下会发生什么>

这是我尝试过的范围:

AllSites.Write Site.Write - 重定向具有 invalid_client 和 error_description = AADSTS650053:应用程序“”请求资源“00000003-0000-0000-c000-000000000000”上不存在的范围“AllSites.Write”。联系应用程序供应商。

https://{tenantname}.sharepoint.com/AllSites.Write https://.sharepoint.com/Site.Write - 重定向有 invalid_client 错误描述 = AADSTS650053:应用程序 '' 要求范围 'Site.Write'资源'00000003-0000-0ff1-ce00-000000000000'上不存在。联系应用程序供应商。

https://{tenantname}.sharepoint.com/.default - 这通过

我不明白 Scope=.Default 如何不包括应用程序注册的允许权限。而且我绝对不明白为什么 AllSites.Write 范围在明确指定时会失败。

如果有帮助,我还使用特定于租户的授权端点而不是“通用”尝试了上述所有方法: https ://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorize


UPDATE2:更多范围变化:

我终于找到了一个有效的神奇组合:

对 /authorize/token 端点使用基于租户的 URI,并使用 {tenanturl}\AllSites.Write 作为范围(不要指定 Site.Write 范围):

https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorize?response_type=code&client_id={clientid}&redirect_uri={redirecturi}&scope=https%3A%2F%2F{tenantname}.sharepoint.com %2FAllSites.Write

生成的 JWT 具有以下内容:“scp”:“AllSites.Write User.Read”

我对为什么不允许 Site.Write 感到完全困惑。我想 AllSites.Write 是 Site.Write 的超集,所以可能不需要?

到目前为止,我所有的测试都是在我自己的租户上进行的,下一步是在不同的租户上进行测试,并确保它确实在那里也能正常工作。

标签: sharepointazure-active-directorysharepoint-online

解决方案


我终于找到了一个有效的神奇组合:

  1. 使用https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorizehttps://login.microsoftonline.com/{tenantid}/oauth2/v2.0/token端点

  2. 为范围指定 {tenanturl}\AllSites.Write (不要指定 Site.Write 范围 - 这是主要问题):

https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorize?response_type=code&client_id={clientid}&redirect_uri={redirecturi}&scope=https%3A%2F%2F{tenantname}.sharepoint.com %2FAllSites.Write

生成的 JWT 具有以下内容:“scp”:“AllSites.Write User.Read”

这适用于租户,并为我们提供所需的访问权限。

为了彻底起见,我们还指定了offline_access 范围,因此除了access_token 之外,我们还获得了一个refresh_token。


推荐阅读