使用具有指定存储 class 的 boto3 生成签名 S3 url
Generate signed S3 url using boto3 with specified storage class
我可以使用 generate_presigned_url()
和 generate_presigned_post()
将文件成功上传到 S3,而无需指定存储 class。
我一尝试指定存储 class 就收到错误。
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'})
失败
The request signature we calculated does not match the signature you
provided. Check your key and signing method.
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)
失败
Invalid according to Policy: Extra input fields: StorageClass
我已经用 "Storage-Class"、"x-amz-storage-class" 和各种不同的键名尝试了后一种方法,结果相同。
我哪里错了?
更新:更多信息
我不认为我有任何权限问题,因为这个有效:
s3_client.put_object(Bucket=bucket,Key='test.txt', StorageClass='INTELLIGENT_TIERING', Body=binary_data)
此外,如果我将 INTELLIGENT_TIERING
替换为 STANDARD
,我会收到与上面提到的 generate_presigned_url()
相同的签名不匹配错误。似乎不是新 class 不受支持的问题。
很可能定义存储的能力 class 被您的 AWS IAM 权限阻止:
By default s3:PutObject stores objects using the STANDARD storage class, but you can use the x-amz-storage-class request header to specify a different storage class.
When granting the s3:PutObject permission, you can use the s3:x-amz-storage-class condition key to restrict which storage class to use when storing uploaded objects. For more information about storage classes, see Storage Classes.
您是否可以共享为 S3 存储桶上传设置的 IAM 权限?
假设您有权访问 IAM 权限,您可能会发现添加了如下限制:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::examplebucket/*"
],
"Condition": {
"StringEquals": {
"s3:x-amz-storage-class": [
"STANDARD"
]
}
}
}
]
}
By adding the 'StorageClass': 'STANDARD_IA' into the params you're
including it as part of the signature as a signed header, this is just
how S3 serializes the storage class. All headers that are signed need
to be sent with the request when you used the presigned url. In this
case you would need to include the following header in your PUT
request:
headers = {'x-amz-storage-class': 'STANDARD_IA'}
调用通过 generate_presigned_url 生成的 url 时,我没有在客户端中包含 header 'x-amz-storage-class',因为我假设 url 包含 S3 所需的所有信息。添加它解决了这个问题。
我可以使用 generate_presigned_url()
和 generate_presigned_post()
将文件成功上传到 S3,而无需指定存储 class。
我一尝试指定存储 class 就收到错误。
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'})
失败
The request signature we calculated does not match the signature you provided. Check your key and signing method.
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)
失败
Invalid according to Policy: Extra input fields: StorageClass
我已经用 "Storage-Class"、"x-amz-storage-class" 和各种不同的键名尝试了后一种方法,结果相同。
我哪里错了?
更新:更多信息
我不认为我有任何权限问题,因为这个有效:
s3_client.put_object(Bucket=bucket,Key='test.txt', StorageClass='INTELLIGENT_TIERING', Body=binary_data)
此外,如果我将 INTELLIGENT_TIERING
替换为 STANDARD
,我会收到与上面提到的 generate_presigned_url()
相同的签名不匹配错误。似乎不是新 class 不受支持的问题。
很可能定义存储的能力 class 被您的 AWS IAM 权限阻止:
By default s3:PutObject stores objects using the STANDARD storage class, but you can use the x-amz-storage-class request header to specify a different storage class.
When granting the s3:PutObject permission, you can use the s3:x-amz-storage-class condition key to restrict which storage class to use when storing uploaded objects. For more information about storage classes, see Storage Classes.
您是否可以共享为 S3 存储桶上传设置的 IAM 权限?
假设您有权访问 IAM 权限,您可能会发现添加了如下限制:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::examplebucket/*"
],
"Condition": {
"StringEquals": {
"s3:x-amz-storage-class": [
"STANDARD"
]
}
}
}
]
}
By adding the 'StorageClass': 'STANDARD_IA' into the params you're including it as part of the signature as a signed header, this is just how S3 serializes the storage class. All headers that are signed need to be sent with the request when you used the presigned url. In this case you would need to include the following header in your PUT request:
headers = {'x-amz-storage-class': 'STANDARD_IA'}
调用通过 generate_presigned_url 生成的 url 时,我没有在客户端中包含 header 'x-amz-storage-class',因为我假设 url 包含 S3 所需的所有信息。添加它解决了这个问题。