您提供的授权机制不受支持。请使用AWS4-HMAC-SHA256。

173

当我尝试上传文件到新的法兰克福区域的S3存储桶时,我收到一个错误AWS::S3::Errors::InvalidRequest The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256. US Standard 区域一切正常。

脚本:

backup_file = '/media/db-backup_for_dev/2014-10-23_02-00-07/slave_dump.sql.gz'
s3 = AWS::S3.new(
    access_key_id:     AMAZONS3['access_key_id'],
    secret_access_key: AMAZONS3['secret_access_key']
)

s3_bucket = s3.buckets['test-frankfurt']

# Folder and file name
s3_name = "database-backups-last20days/#{File.basename(File.dirname(backup_file))}_#{File.basename(backup_file)}"

file_obj = s3_bucket.objects[s3_name]
file_obj.write(file: backup_file)

aws-sdk(1.56.0)

如何修复?

谢谢。


1
这个答案解决了我的问题: https://dev59.com/jZLea4cB1Zd3GeqP2XSB#34495454 - Bahadir Tasdemir
你必须告诉boto3客户端你所在的地区,所以 s3_client = boto3.client('s3', region_name='eu-west-2') - undefined
25个回答

176
AWS4-HMAC-SHA256,也称为签名版本4("V4"),是S3支持的两种身份验证方案之一。
所有区域都支持V4,但是美国标准¹和许多其他区域(但不是全部)还支持另一种较旧的方案,即签名版本2("V2")。
根据http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html... 2014年1月后部署的新S3区域仅支持V4。
由于法兰克福在2014年末推出,因此不支持V2,这就是此错误建议您正在使用的内容。 http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html解释了如何在各种具有该功能的SDK中启用V4,假设您正在使用具有该功能的SDK。
如果上述方法无效,我猜测一些旧版本的SDK可能不支持此选项,因此您可能需要使用更新版本的SDK。请注意保留HTML标签。

¹US Standard 曾是基于 us-east-1 区域的 S3 区域部署的旧名称。自此回答发布之时起,"Amazon S3 将 US Standard 区域更名为 US East (N. Virginia) 区域以符合 AWS 区域命名惯例。" 实际上,这只是一个命名的改变。


这让自带于 Fedora 20 的 s3cmd-1.5.0-0.alpha3.fc20.noarch 遇到了困难。而目前最新版的 stumps 1.5.0-rc1 似乎也无法解决该问题。 - David Tonhofer
1
@DavidTonhofer 看起来没错。看起来 s3cmd 的开发人员还没有实现 AWS4-HMAC-SHA256:https://github.com/s3tools/s3cmd/issues/402 - Michael - sqlbot
2
"Michael - sqlbot",我现在改用 "awscli" 了。对于那些急于使用的人:yum install python-pip; pip install awscli; aws configure; aws --region=eu-central-1 s3 ls s3://$BUCKET 等等... - David Tonhofer
aws-sdk v2 似乎很好地支持了 AWS4-HMAC-SHA256 "V4" 认证(相关 问题)。 - Jeewes
以下是AWS推出各个区域的时间线:https://en.wikipedia.org/wiki/Timeline_of_Amazon_Web_Services - William Turrell
显示剩余2条评论

88

使用Node,尝试一下

var s3 = new AWS.S3( {
    endpoint: 's3-eu-central-1.amazonaws.com',
    signatureVersion: 'v4',
    region: 'eu-central-1'
} );

40

您应该在config中设置signatureVersion: 'v4',以使用新的签名版本:

AWS.config.update({
    signatureVersion: 'v4'
});

适用于JS SDK。


3
救了我的一天!不确定为什么这个选项没有更多的宣传。 - André Werlang

40

如果您正在使用 boto3 Python SDK ),请使用以下代码

from botocore.client import Config


s3 = boto3.resource(
    's3',
    aws_access_key_id='xxxxxx',
    aws_secret_access_key='xxxxxx',
    config=Config(signature_version='s3v4')
)

7
我收到错误信息 AuthorizationQueryParametersError,提示无法解析参数 X-Amz-Credential,原因是所在地区为 us-east-1,而需要的是 us-east-2。因此,我在上述代码中添加了 region_name='us-east-2'。请注意,翻译过程中尽可能保留原文意思,使语言更加通俗易懂。 - Aseem

36

仍然是使用boto的人们最好的答案,谢谢 <3 - because_im_batman
我需要的正是这个。 - fanni

15

PHP SDK也存在类似问题,以下代码可以解决:

$s3Client = S3Client::factory(array('key'=>YOUR_AWS_KEY, 'secret'=>YOUR_AWS_SECRET, 'signature' => 'v4', 'region'=>'eu-central-1'));

重要的是 signatureregion


需要指定区域吗? - Chirag Mehta

8
AWS_S3_REGION_NAME = "ap-south-1"

AWS_S3_SIGNATURE_VERSION = "s3v4"

在冲浪了24小时之后,这也节省了我的时间。


这个很好用,如果你的区域名称不是“ap-south-1”,你只需要更改它以适应你自己的区域名称。 - sikaili99
不需要进行编码更改!设置这两个环境变量,boto 就可以正常工作了。 - Stevko

8

Flask代码(boto3)

不要忘记导入Config。如果您有自己的配置类,请更改其名称。

from botocore.client import Config

s3 = boto3.client('s3',config=Config(signature_version='s3v4'),region_name=app.config["AWS_REGION"],aws_access_key_id=app.config['AWS_ACCESS_KEY'], aws_secret_access_key=app.config['AWS_SECRET_KEY'])
s3.upload_fileobj(file,app.config["AWS_BUCKET_NAME"],file.filename)
url = s3.generate_presigned_url('get_object', Params = {'Bucket':app.config["AWS_BUCKET_NAME"] , 'Key': file.filename}, ExpiresIn = 10000)

是的。它在Django中也可以工作,但仍然无法理解没有配置和区域设置它在本地运行良好,但无法在AWS托管服务器上运行相同的内容。 - iampritamraj
1
Boto3会在不同的配置位置查找配置值,直到找到为止。在搜索配置值时,Boto3遵循以下查找顺序:
  1. 通过config参数创建并传递的Config对象
  2. 环境变量
  3. ~/.aws/config文件
- undefined

3
使用boto3,代码如下:
s3_client = boto3.resource('s3', region_name='eu-central-1')

或者

s3_client = boto3.client('s3', region_name='eu-central-1')

你有两个s3_client吗? - PolarBear10

3

在Java中,我需要设置一个属性

System.setProperty(SDKGlobalConfiguration.ENFORCE_S3_SIGV4_SYSTEM_PROPERTY, "true")

并将该地区添加到s3Client实例中。

s3Client.setRegion(Region.getRegion(Regions.EU_CENTRAL_1))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接