amazon-web-services - 使用具有指定存储类的 boto3 生成签名的 S3 url
问题描述
我可以使用这两种方法成功地将文件上传到 S3 generate_presigned_url()
,而generate_presigned_post()
无需指定存储类。
一旦我尝试指定一个存储类,我就会收到一个错误。
import boto3
from botocore.client import Config
s3_client = boto3.client(service_name='s3',config=Config(signature_version='s3v4'))
s3_client.generate_presigned_url(ClientMethod='put_object',Params={'Bucket':bucket,'Key':'test.txt', 'StorageClass':'INTELLIGENT_TIERING'})
失败了
我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法。
import boto3
from botocore.client import Config
s3_client = boto3.client(service_name='s3',config=Config(signature_version='s3v4')
parts=s3_client.generate_presigned_post(Bucket=bucket,Key='test.txt', Fields={'StorageClass':'INTELLIGENT_TIERING'})
files = {'file':open('test.txt')}
response=requests.post(parts['url'], data=parts['fields'], files=files)
失败了
根据策略无效:额外输入字段:StorageClass
我用“Storage-Class”、“x-amz-storage-class”和各种不同的键名尝试了后一种方法,结果相同。
我哪里错了?
更新:更多信息
我不相信我有任何权限问题,因为这有效:
s3_client.put_object(Bucket=bucket,Key='test.txt', StorageClass='INTELLIGENT_TIERING', Body=binary_data)
此外,generate_presigned_url()
如果我INTELLIGENT_TIERING
用STANDARD
. 似乎不是不支持新类的问题。
解决方案
通过将 'StorageClass': 'STANDARD_IA' 添加到参数中,您将其作为签名的一部分作为签名标头包含在内,这就是 S3 序列化存储类的方式。当您使用预签名的 url 时,所有已签名的标头都需要与请求一起发送。在这种情况下,您需要在 PUT 请求中包含以下标头:
标头 = {'x-amz-storage-class': 'STANDARD_IA'}
在调用通过 generate_presigned_url 生成的 url 时,我没有在客户端中包含标头“x-amz-storage-class”,因为我假设该 url 包含 S3 所需的所有信息。添加它解决了这个问题。
推荐阅读
- c# - JArray 中 JArray 的 OrderByDescending
- javascript - AWS S3 - 我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法
- java - 我希望能够在 Anylogic 中 sleep()
- laravel - Laravel - 谷歌折线图不显示
- python - michelson-morley 实验的模拟返回了错误的时间值?
- spring-boot - 3 xxx.setAttribute() 的区别
- android - 在 MaterialToolbar 中更改 Searchview 的文本颜色不起作用
- neo4j - neo4j - 通过 url 构造密码查询
- javascript - 我该如何创造这样的东西?
- python - 合并多行输出?