整个存储桶的预签名 url

Posted

技术标签:

【中文标题】整个存储桶的预签名 url【英文标题】:Pre-signed url for the whole bucket 【发布时间】:2019-11-16 04:30:33 【问题描述】:

我正在使用 gsutil 创建用于上传的预签名 URL。命名存储桶中的对象时,我可以成功上传。来自 gsutil 的以下代码片段适用于 curl PUT:

gsutil signurl -m PUT -d 10m -r eu ~/.ssh/mycreds.json gs://cjreyn-bucket-0/myobjectname.txt

但是,当仅指定存储桶名称而不是其中的对象时,上传任意对象不起作用:

gsutil signurl -m PUT -d 10m -r eu ~/.ssh/mycreds.json gs://cjreyn-bucket-0/

这会从 curl 中返回以下内容:

<?xml version='1.0' encoding='UTF-8'?><Error><Code>BucketAlreadyOwnedByYou</Code><Message>Your previous request to create the named bucket succeeded and you already own it.</Message></Error>

我的卷曲线如下(为简洁起见,将签名 URL 替换为):

curl -X PUT --upload-file myobj.txt "<mysignedurl>"

是否甚至可以为整个存储桶而不是其中的每个对象创建用于上传和下载的签名 URL?

【问题讨论】:

【参考方案1】:

不,这是不可能的。

签名的 URL 仅授权一个特定的请求,该请求在签名前转换为 canonical form。然后服务组装相同的表示并计算签名应该是什么,此时对于给定动词(例如PUT)、资源(桶+密钥)的有效签名只有一个正确答案,一组凭据、时间戳和过期时间。

签名实际上并不包括被授权的请求参数的副本——它们是在发出请求时从请求中推断出来的——因此没有将任何信息传递给服务的机制可用于指定例如应该允许通配符路径。

为存储桶本身签署一个PUT URL 会授权该 URL 的持有者发送使用该名称创建存储桶的请求,正如您收到的错误所暗示的那样。

一种解决方案是创建一个 Web 服务,该服务使用请求中提供的参数的预签名 URL 来响应授权请求(在您的环境中可能意味着什么,例如基于用户的 Web cookie),一旦Web 服务验证它们。请记住,如果这是一个需要写入存储桶的网站或应用程序,您永远不能相信这些东西只会发出合理/安全的请求,因为它们不在您的控制范围内——因此参数验证至关重要避免恶意行为。

另一个选项可能是awscurl,它是一个类似 curl 的工具,它自己执行请求签名。 GCS 具有 AWS 兼容模式,因此这可能意味着您可以按原样使用此工具,或者可以对其进行调整,或者可能有 GCS 的类似工具。但我假设您需要其他地方的签名 URL,而不是本地机器,否则您只会使用 gsutil 进行上传。

【讨论】:

【参考方案2】:

这是不可能的,因为预签名的 URL 仅对一个对象有效。

【讨论】:

以上是关于整个存储桶的预签名 url的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Picasso 使用动态 URL 缓存来自 S3 存储桶的图像?

AWS S3 存储桶预签名 URL

如何使用签名的 URL 将文件上传到谷歌云存储桶

AWS CloudFront 签名 URL 的访问被拒绝

Cloudfront URL 永不过期

如何将文件上传到 AWS 中的预签名 URL?