尝试使用 REST API 公开对象时出现“拒绝访问。提供的范围未经授权”错误

Posted

技术标签:

【中文标题】尝试使用 REST API 公开对象时出现“拒绝访问。提供的范围未经授权”错误【英文标题】:"Access Denied. Provided scope(s) are not authorized" error when trying to make objects public using the REST API 【发布时间】:2020-04-25 04:47:05 【问题描述】:

我正在尝试为 Google Cloud Storage 存储桶中的单个对象设置权限,以使它们公开可见,遵循 the steps indicated in Google's documentation。当我尝试使用我们的应用程序服务帐户发出这些请求时,它失败并显示 HTTP 状态 403 和以下消息:

访问被拒绝。提供范围未经授权。

其他请求工作正常。当我尝试做同样的事情但通过为我的个人帐户提供令牌时,对对象的 ACL 的 PUT 请求工作......大约 50% 的时间(其余时间是 503 错误,可能相关也可能不相关)。

更改服务帐户的 IAM 策略以匹配我的 - 它通常具有存储管理员和一些其他附带角色 - 没有帮助,即使我赋予它整体 Owner IAM 角色,这是我所拥有的。

既不使用XML API 也不使用JSON 版本会有所不同。该请求有时适用于我的个人凭据,这向我表明该请求的格式不正确,但必须有其他我迄今为止忽略的东西。有什么想法吗?

【问题讨论】:

您是否在该存储桶上使用统一的存储桶级访问策略? 您是否在同一环境中为用户和服务帐户凭据运行它?否则,它可能是范围不足的 GCE 实例 您检查过this reference 的 GCS 作用域吗? @OliverAragon 不,我们不能只创建一个公共存储桶,因为并非存储桶中的所有文件都是公开的。 @GuillemXercavins 是的,我想是的。 【参考方案1】:

如果您使用的是默认计算引擎服务帐户,请检查服务帐户的范围。默认情况下,范围受到限制,对于 GCS,它是只读的。清除缓存时使用 rm -r ~/.gsutil 清除缓存

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案2】:

按照您提供的documentation,考虑以下几点:

存储桶的访问控制系统必须细粒度(不统一)。

为了使对象公开可用,请确保存储桶未启用公共访问阻止。查看此link 了解更多信息。

授予服务帐号在存储桶中的适当权限。 Storage Legacy Object Owner 角色 (roles/storage.legacyObjectOwner) 需要编辑对象 ACL,如 here 所示。可以为单个存储桶授予此角色,而不是为项目授予此角色。

按照文档中的说明创建json 文件。

使用gcloud auth application-default print-access-token 获取授权访问令牌并在 API 调用中使用它。 API 调用应如下所示:

curl -X POST --data-binary @JSON_FILE_NAME.json \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" \
  "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME/acl"

【讨论】:

【参考方案3】:

您需要在创建实例时添加 OAuth 范围:cloud-platform。看:https://cloud.google.com/sdk/gcloud/reference/compute/instances/create#--scopes

选择“允许完全访问所有 Cloud API”或选择细粒度方法

【讨论】:

【参考方案4】:

尝试从 GCE 实例访问 GCS 并收到此错误消息时... 默认scope 是devstorage.read_only,这会阻止所有写操作。

不确定是否需要范围 https://www.googleapis.com/auth/cloud-platform,而在默认情况下给出范围 https://www.googleapis.com/auth/devstorage.read_only(例如,读取启动脚本)。范围应该是:https://www.googleapis.com/auth/devstorage.read_write


并且可以使用gcloud beta compute instances set-scopes 来编辑实例的范围:

gcloud beta compute instances set-scopes $INSTANCE_NAME \
  --project=$PROJECT_ID \
  --zone=$COMPUTE_ZONE \
  --scopes=https://www.googleapis.com/auth/devstorage.read_write \
  --service-account=$SERVICE_ACCOUNT

也可以传递所有已知的作用域别名,例如:--scopes=cloud-platform。由于权限的原因,该命令必须在实例外部运行 - 并且必须关闭实例才能更改服务帐户。

【讨论】:

作为说明,这也解决了我从计算引擎机器写入存储桶的问题(谢谢,由于某种原因,我没有使用我正在考虑的术语在文档中找到这个)。

以上是关于尝试使用 REST API 公开对象时出现“拒绝访问。提供的范围未经授权”错误的主要内容,如果未能解决你的问题,请参考以下文章

尝试创建 Quickblox 群聊对话框,使用 REST API 登录用户时出现错误。

在 rest api 中发布请求时出现 415 错误,尝试运行 cms 查询

尝试 GET 时出现 WCF REST 404

Postman 在使用 REST Api 时出现意外的“S”

如何修复在 Django Rest Framework 中使用 REST API 登录时出现的 CSRF 错误?

从sharepoint rest api下载文件时出现400错误