【发布时间】:2018-04-10 16:35:42
【问题描述】:
我正在为一项服务编写一个客户端,该服务提供一个签名的 url 用于上传。这适用于较小的上传,但对于可以从使用分段上传中受益的较大上传则失败。
授权文档建议我可以在 URL 中或通过 Authorization 标头使用提供的签名和访问密钥 ID。我已经尝试使用标头方法开始分段上传,但访问被拒绝。当我使用查询字符串方法时,我得到一个不允许的方法(在这种情况下为 POST)。
我正在使用 boto 来生成 URL。例如:
import boto
c = boto.connect_s3()
bucket = c.get_bucket('my-bucket')
key = boto.s3.key.Key(bucket, 'my-big-file.gz')
signed_url = key.generate_url(60 * 60, 'POST') # expires in an hour
然后,当尝试使用签名 URL 开始分段上传时,我正在执行以下操作:
import requests
url = signed_url + '&uploads'
resp = requests.post(url)
这会返回一个不允许的方法。
这种策略可行吗?有没有更好的方法来为特定资源提供有限的凭据以允许大型分段上传?
更新
我设法找到了一个稍微更具体的错误,这让我认为这是不可能的。不幸的是,我收到 403 表示签名与请求不匹配。
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you
provided. Check your key and signing method.</Message>
<StringToSignBytes>.../StringToSignBytes>
<RequestId>...</RequestId>
<HostId>...</HostId>
<SignatureProvided>...</SignatureProvided>
<StringToSign>POST
1402941975
/my-sandbox/test-mp-upload.txt?uploads</StringToSign>
<AWSAccessKeyId>...</AWSAccessKeyId>
</Error>
这让我觉得我将无法使用签名的 URL,因为签名不匹配。
更新
我认为使用签名 URL 进行分段上传是不合理的。虽然我怀疑这在技术上是可行的,但它并不实用。原因是签名的 URL 要求 URL、标头和请求方法都完全匹配才能按预期工作。由于分段上传需要初始化上传,上传每个部分并完成(或取消)上传,因此为每个步骤生成 URL 会有些痛苦。
相反,我发现可以创建一个联合令牌来提供对存储桶中特定键的读/写访问权限。这最终变得更加实用和简单,因为我可以立即使用 boto,就好像我有凭据一样。
【问题讨论】:
-
我想 url 应该是这样的:
POST /ObjectName?uploads ...,你有没有尝试把upload关键字放在键名后面? -
@mr0re1 很好。我更新了问题,但没有任何改变。
-
它改变响应错误,
SignatureDoesNotMatch而不是Not Allowed这意味着无效的请求语法
标签: python amazon-web-services boto