sharepoint - SharePoint Online 多租户 REST 调用对肯定存在的资源返回 404
问题描述
我正在尝试访问 SharePoint Online REST API(这是手动编码的 REST 调用,没有使用任何库)。
使用授权授予流程获取访问令牌,如下所示:
我发送浏览器https://login.microsoftonline.com/common/oauth2/authorize? ...
这重定向到我们从中提取访问代码的处理程序端点
我通过以下方式获取租户 ID: GET https://{tenantname}.sharepoint.com/_vti_bin/client.svc 然后从 WWW-Authenticate 标头中提取租户 ID
然后我发布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 - 这通过
- 但生成的 JWT 只有 scp=User.Read
- 以下工作: GET https://{tenantname}.sharepoint.com/_api/search/query?querytext=
- 但以下返回 404: GET https://{tenantname}.sharepoint.com/_api/web/getfilebyserverrelativeurl('/TestFiles/test.pdf')
我不明白 Scope=.Default 如何不包括应用程序注册的允许权限。而且我绝对不明白为什么 AllSites.Write 范围在明确指定时会失败。
如果有帮助,我还使用特定于租户的授权端点而不是“通用”尝试了上述所有方法: https ://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorize
UPDATE2:更多范围变化:
我终于找到了一个有效的神奇组合:
对 /authorize和/token 端点使用基于租户的 URI,并使用 {tenanturl}\AllSites.Write 作为范围(不要指定 Site.Write 范围):
生成的 JWT 具有以下内容:“scp”:“AllSites.Write User.Read”
我对为什么不允许 Site.Write 感到完全困惑。我想 AllSites.Write 是 Site.Write 的超集,所以可能不需要?
到目前为止,我所有的测试都是在我自己的租户上进行的,下一步是在不同的租户上进行测试,并确保它确实在那里也能正常工作。
解决方案
我终于找到了一个有效的神奇组合:
使用https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorize和https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/token端点
为范围指定 {tenanturl}\AllSites.Write (不要指定 Site.Write 范围 - 这是主要问题):
生成的 JWT 具有以下内容:“scp”:“AllSites.Write User.Read”
这适用于租户,并为我们提供所需的访问权限。
为了彻底起见,我们还指定了offline_access 范围,因此除了access_token 之外,我们还获得了一个refresh_token。
推荐阅读
- sql-server - SQL Server 导入导出向导将视图转换为表
- r - 如何在R中的数据框中保留输入的值
- python - gRPC-python:在 gRPC 服务器运行时切换 Servicer?(模拟-实模式切换)
- python - 为什么我收到 UserWarning:Matplotlib 当前正在使用 ps,这是一个非 GUI 后端,所以无法显示该图
- c - 可能的 4 位数字,其单个数字总和等于 n
- solidity - Solidity问题将参数传递给函数
- microsoft-graph-api - Microsoft Graph“消息”增量请求使用日期筛选器截断太多结果
- elasticsearch - Elasticsearch:在数组中找到完全匹配
- angular - Angular Storybook 组件是两个模块错误的一部分
- eclipse - 在两台计算机之间共享 Eclipse 工作区