生成预签名的URL以上传到S3存储桶

时间:2018-08-24 02:36:05

标签: amazon-web-services amazon-s3 pre-signed-url

我正在尝试为AWS上的S3存储桶生成一个预签名URL,以将文件上传到这样的位置:

$ aws s3 presign s3://mybucket/somefolder/

然后我使用该URL上传文件:

$ curl "https://mybucket.s3.amazonaws.com/somefolder/?AWSAccessKeyId=***&Signature=***&Expires=***"  --upload-file "./file"

但是它会打印出XML错误:

<?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>
  <AWSAccessKeyId>***********</AWSAccessKeyId>
  <StringToSign>PUT


    ************
    /mybucket/somefolder/</StringToSign>
  <SignatureProvided>**************</SignatureProvided>
  <StringToSignBytes>**************</StringToSignBytes>
  <RequestId>************</RequestId>
  <HostId>************</HostId>
</Error>

我在做什么错了?

[更新]

好,所以我必须在预签名URL中指定对象名称。所以我做到了,但是我仍然面临着同样的错误消息:

$ aws s3 presign s3://mybucket/someobject

然后:

$ curl "https://mybucket.s3.amazonaws.com/someobject?AWSAccessKeyId=***&Signature=***&Expires=***"  --upload-file "./file"

我将得到与以前完全相同的错误。为了确保这不是权限问题,我对此进行了测试:

$ aws s3 cp ./file s://mybucket/

文件被复制!有什么建议吗?

[更新]

我什至对存储桶中实际存在的对象进行了测试,并成功下载了该对象。但是我仍然无法写入对象,只能读取。

2 个答案:

答案 0 :(得分:2)

看来cli命令aws s3 presign仅用于GetObject。参数'get_object'硬编码在source code中。 (请参阅第671行)

您可以使用其他SDK(例如boto3)为PutObject创建预签名的URL。确保设置客户端方法'put_object'

答案 1 :(得分:1)

S3签名的URL是基于每个对象创建的,不能为前缀(文件夹)生成。如果要将File.AppendAllText()上传到some_file,则必须为整个对象密钥生成一个已签名的url:

some_folder

请参见this AWS documentation