我正在尝试为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/
文件被复制!有什么建议吗?
[更新]
我什至对存储桶中实际存在的对象进行了测试,并成功下载了该对象。但是我仍然无法写入对象,只能读取。
答案 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