158

I get an error AWS::S3::Errors::InvalidRequest The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256. when I try upload file to S3 bucket in new Frankfurt region. All works properly with US Standard region.

Script:

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)

How to fix it?

Thank you.

4

22 回答 22

165

AWS4-HMAC-SHA256,也称为签名版本 4,(“V4”)是 S3 支持的两种身份验证方案之一。

所有区域都支持 V4,但 US-Standard¹ 和许多(但不是全部)其他区域也支持另一个较旧的方案,签名版本 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 的较新版本。


¹US Standard是基于该us-east-1区域的 S3 区域部署的旧名称。自最初编写此答案以来, “Amazon S3 将美国标准区域重命名为美国东部(弗吉尼亚北部)区域,以符合 AWS 区域命名约定。” 出于所有实际目的,这只是命名的改变。

于 2014-10-23T22:03:48.867 回答
81

使用节点,尝试

var s3 = new AWS.S3( {
    endpoint: 's3-eu-central-1.amazonaws.com',
    signatureVersion: 'v4',
    region: 'eu-central-1'
} );
于 2015-07-26T11:10:04.263 回答
39

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

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

适用于JSsdk。

于 2015-03-24T13:28:40.920 回答
33

对于使用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')
)
于 2016-12-22T07:06:09.487 回答
28

我一直在使用 Django,我必须添加这些额外的配置变量才能使其工作。(除了https://simpleisbetterthancomplex.com/tutorial/2017/08/01/how-to-setup-amazon-s3-in-a-django-project.html中提到的设置)。

AWS_S3_REGION_NAME = "ap-south-1"

或在 boto3 版本 1.4.4 之前:

AWS_S3_REGION_NAME = "ap-south-1"

AWS_S3_SIGNATURE_VERSION = "s3v4"
于 2018-10-04T08:55:56.473 回答
15

PHP SDK的类似问题,这有效:

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

重要的一点是signatureregion

于 2015-01-30T14:41:40.617 回答
6
AWS_S3_REGION_NAME = "ap-south-1"

AWS_S3_SIGNATURE_VERSION = "s3v4"

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

于 2020-05-07T02:09:31.553 回答
5

烧瓶代码 (boto3)

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

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)
于 2020-06-14T21:52:27.667 回答
3

使用boto3,这是代码:

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

或者

s3_client = boto3.client('s3', region_name='eu-central-1')
于 2017-07-26T07:50:05.687 回答
3

在Java中我必须设置一个属性

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

并将区域添加到 s3Client 实例。

s3Client.setRegion(Region.getRegion(Regions.EU_CENTRAL_1))
于 2016-11-12T00:04:03.137 回答
2

For thumbor-aws, that used boto config, i needed to put this to the $AWS_CONFIG_FILE

[default]
aws_access_key_id = (your ID)
aws_secret_access_key = (your secret key)
s3 =
    signature_version = s3

So anything that used boto directly without changes, this may be useful

于 2017-03-22T15:52:05.963 回答
1

就我而言,请求类型是错误的。我正在使用 GET(dumb) 它必须是 PUT。

于 2020-06-16T05:32:51.160 回答
1

检查您的 AWS S3 存储桶区域并在连接请求中传递正确的区域。

在 My Senario 中,我为亚太地区(孟买)设置了“ APSouth1 ”

using (var client = new AmazonS3Client(awsAccessKeyId, awsSecretAccessKey, RegionEndpoint.APSouth1))
{
    GetPreSignedUrlRequest request1 = new GetPreSignedUrlRequest
    {
        BucketName = bucketName,
        Key = keyName,
        Expires = DateTime.Now.AddMinutes(50),
    };
    urlString = client.GetPreSignedURL(request1);
}
于 2019-12-16T07:08:31.897 回答
1

这是我在 Python 中使用的函数

def uploadFileToS3(filePath, s3FileName):
    s3 = boto3.client('s3', 
                    endpoint_url=settings.BUCKET_ENDPOINT_URL,
                    aws_access_key_id=settings.BUCKET_ACCESS_KEY_ID,
                    aws_secret_access_key=settings.BUCKET_SECRET_KEY,
                    region_name=settings.BUCKET_REGION_NAME
                    )
    try:
        s3.upload_file(
            filePath, 
            settings.BUCKET_NAME, 
            s3FileName
            )

        # remove file from local to free up space
        os.remove(filePath)

        return True
    except Exception as e:
        logger.error('uploadFileToS3@Error')
        logger.error(e)
        return False
于 2021-03-04T08:43:36.523 回答
1

对于 Android SDK,setEndpoint 解决了这个问题,尽管它已被弃用。

CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
                context, "identityPoolId", Regions.US_EAST_1);
AmazonS3 s3 = new AmazonS3Client(credentialsProvider);
s3.setEndpoint("s3.us-east-2.amazonaws.com");
于 2017-04-16T22:09:26.793 回答
1

基本上这个错误是因为我使用的是旧版本的 aws-sdk 并且我更新了版本所以发生了这个错误。

在我使用节点 js 的情况下,我signatureVersion在 parmas 对象中使用如下:

const AWS_S3 = new AWS.S3({
  params: {
    Bucket: process.env.AWS_S3_BUCKET,
    signatureVersion: 'v4',
    region: process.env.AWS_S3_REGION
  }
});

然后我将签名从 params 对象中取出并像魅力一样工作:

const AWS_S3 = new AWS.S3({
  params: {
    Bucket: process.env.AWS_S3_BUCKET,
    region: process.env.AWS_S3_REGION
  },
  signatureVersion: 'v4'
});
于 2019-07-29T11:45:01.310 回答
1

对于 Boto3 ,请使用此代码。

import boto3
from botocore.client import Config


s3 = boto3.resource('s3',
        aws_access_key_id='xxxxxx',
        aws_secret_access_key='xxxxxx',
        region_name='us-south-1',
        config=Config(signature_version='s3v4')
        )
于 2020-01-05T19:47:46.957 回答
1

django/boto3/django-storages 的超新星答案和我一起工作:

AWS_S3_REGION_NAME = "ap-south-1"

或在 boto3 版本 1.4.4 之前:

AWS_S3_REGION_NAME = "ap-south-1"

AWS_S3_SIGNATURE_VERSION = "s3v4"

只需将它们添加到您的 settings.py 并相应地更改区域代码

您可以从以下位置检查 aws 区域: 在此处输入链接描述

于 2020-08-05T09:06:29.300 回答
0

试试这个组合。

const s3 = new AWS.S3({
  endpoint: 's3-ap-south-1.amazonaws.com',       // Bucket region
  accessKeyId: 'A-----------------U',
  secretAccessKey: 'k------ja----------------soGp',
  Bucket: 'bucket_name',
  useAccelerateEndpoint: true,
  signatureVersion: 'v4',
  region: 'ap-south-1'             // Bucket region
});
于 2020-05-24T21:38:15.413 回答
0

有时默认版本不会更新。添加此命令

AWS_S3_SIGNATURE_VERSION = "s3v4"

settings.py

于 2019-02-27T10:55:58.133 回答
0

我被困了 3 天,最后,在阅读了大量博客和答案后,我能够配置 Amazon AWS S3 Bucket。

在 AWS 方面

我假设你已经

  1. 创建了一个 s3 存储桶
  2. 在 IAM 中创建用户

脚步

  1. 配置 CORS 设置

    你存储桶 > 权限 > CORS 配置

    <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    </CORSConfiguration>```
    
    
  2. 生成存储桶策略

您的存储桶 > 权限 > 存储桶策略

应该和这个类似

 {
     "Version": "2012-10-17",
     "Id": "Policy1602480700663",
     "Statement": [
         {
             "Sid": "Stmt1602480694902",
             "Effect": "Allow",
             "Principal": "*",
             "Action": "s3:GetObject",
             "Resource": "arn:aws:s3:::harshit-portfolio-bucket/*"
         }
     ]
 }
PS: Bucket policy should say `public` after this 
  1. 配置访问控制列表

您的存储桶 > 权限 > 访问控制列表

公开访问

PS:访问控制列表应该public在这之后说

  1. 取消阻止公共访问

您的存储桶 > 权限 > 阻止公共访问

编辑并关闭所有选项

**附带说明,如果您正在使用 django 将以下行添加到您settings.py的项目文件中 **

#S3 BUCKETS CONFIG

AWS_ACCESS_KEY_ID = '****not to be shared*****'
AWS_SECRET_ACCESS_KEY = '*****not to be shared******'
AWS_STORAGE_BUCKET_NAME = 'your-bucket-name'

AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

# look for files first in aws 
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

# In India these settings work
AWS_S3_REGION_NAME = "ap-south-1"
AWS_S3_SIGNATURE_VERSION = "s3v4"

于 2020-10-13T10:54:04.280 回答
-1

完整的工作 nodejs 版本:

const AWS = require('aws-sdk');

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


const getPreSignedUrl = async () => {
    const params = {
        Bucket: 'some-bucket-name/some-folder',
        Key: 'some-filename.json',
        Expires: 60 * 60 * 24 * 7
    };
    try {
        const presignedUrl = await new Promise((resolve, reject) => {
            s3.getSignedUrl('getObject', params, (err, url) => {
                err ? reject(err) : resolve(url);
            });
        });
        console.log(presignedUrl);
    } catch (err) {
        if (err) {
            console.log(err);
        }
    }
};

getPreSignedUrl();
于 2021-06-28T18:23:34.027 回答