我想创建一个所谓的“预签名”URL,用于将特定对象 (PUT) 上传到 Amazon S3 存储桶。
到现在为止还挺好。我正在使用 python 库boto创建一个 URL,其中包含所有必要的内容(过期、签名等)。URL 如下所示:
https://<bucketname>.s3.amazonaws.com/<key>?Signature=<sig>&Expires=<expires>&AWSAccessKeyId=<my key id>&x-amz-acl=public-read
注意最后一个参数。
至少,据我了解,这限制了使用此 URL 的人将对象上传到特定存储桶中的特定键,并且还将在对象上设置的罐装 ACL 限制为“公开读取”。
我的最后一个陈述是完全不正确的。
事实证明,如果您使用此 URL,则可以使用 x-amz-acl标头执行以下操作(与具有相同名称的查询字符串参数相反,您必须设置该参数才能使签名检查成功):
- 将其设置为“公开阅读”。对象的权限将包含两个条目:“所有人”的“读取”和存储桶所有者的“完全控制”。这在意料之中。
- 省略 x-amz-acl 标头。对象的权限将与每个存储桶的默认权限相同(存储桶所有者拥有完全控制权)。为什么?
- 将其设置为“公共读写”。结果与(1)中的完全一样。
- 将其设置为“经过身份验证的读取”。“经过身份验证的用户”获得“读取”权限,存储桶拥有者拥有完全控制权。
- 将其设置为“bucket-owner-read”。结果与(2)中的完全一样。存储桶所有者拥有完全控制权,没有定义其他权限。
- 将其设置为“bucket-owner-full-control”。不出所料,存储桶所有者将拥有完全控制权。
- 将其设置为不存在的固定 ACL 名称并得到错误。
这样看来,
- x-amz-acl header不参与签名检查,因为可以随意更改,请求成功。但是,在签名检查期间肯定会考虑查询字符串参数。
- x-amz-acl查询字符串参数不会直接影响对象的权限,因为它自己什么也不做。
- 如果您发送 x-amz-acl 标头,则生成的权限永远不会
- 对存储桶所有者的限制比默认情况下更严格。
- 对非存储桶所有者的限制较少。
- 但是,它们可以对非存储桶所有者更具限制性。也就是说,如果您
x-amz-acl=public-read
在查询字符串中指定,您可以将x-amz-acl
标头设置authenticated-read
为公共可读对象,而不是获取一个对象,该对象只能由经过身份验证的用户读取。
x-amz-acl QS 参数和标题之间的真正关系是什么,同名?有没有办法限制对象的权限,即通过PUT
请求上传到所谓的“预签名”URL?