首页 > 解决方案 > 使用具有指定存储类的 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_TIERINGSTANDARD. 似乎不是不支持新类的问题。

标签: amazon-web-servicesamazon-s3boto3boto

解决方案


根据此评论

通过将 'StorageClass': 'STANDARD_IA' 添加到参数中,您将其作为签名的一部分作为签名标头包含在内,这就是 S3 序列化存储类的方式。当您使用预签名的 url 时,所有已签名的标头都需要与请求一起发送。在这种情况下,您需要在 PUT 请求中包含以下标头:

标头 = {'x-amz-storage-class': 'STANDARD_IA'}

在调用通过 generate_presigned_url 生成的 url 时,我没有在客户端中包含标头“x-amz-storage-class”,因为我假设该 url 包含 S3 所需的所有信息。添加它解决了这个问题。


推荐阅读