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

时间:2014-10-23 16:52:02

标签: ruby amazon-web-services amazon-s3 aws-sdk

当我尝试将文件上传到新法兰克福地区的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)

如何解决?

谢谢。

21 个答案:

答案 0 :(得分:134)

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。


¹US Standard是基于us-east-1区域的S3区域部署的前名称。从这个答案最初写的时候起, "Amazon S3 renamed the US Standard Region to the US East (N. Virginia) Region to be consistent with AWS regional naming conventions."出于所有实际目的,它只是命名的变化。

答案 1 :(得分:48)

使用节点,尝试

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

答案 2 :(得分:24)

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

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

适用于JS sdk。

答案 3 :(得分:17)

对于使用boto3Python 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')
)

答案 4 :(得分:10)

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

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

重要的一位是signatureregion

答案 5 :(得分:5)

我一直在使用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"

AWS_S3_SIGNATURE_VERSION = "s3v4"

答案 6 :(得分:4)

AWS_S3_REGION_NAME = "ap-south-1"

AWS_S3_SIGNATURE_VERSION = "s3v4"

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

答案 7 :(得分:3)

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

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

并将该区域添加到s3Client实例。

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

答案 8 :(得分:2)

对于使用boto配置的thumbor-aws,我需要把它放到$AWS_CONFIG_FILE

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

所以任何直接使用boto而没有改变的东西,这可能是有用的

答案 9 :(得分:2)

使用boto3,这是代码:

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

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

答案 10 :(得分: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");

答案 11 :(得分:1)

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

在我的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);
}

答案 12 :(得分: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')
        )

答案 13 :(得分: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区域: enter link description here

答案 14 :(得分:1)

烧瓶代码(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)

答案 15 :(得分:1)

在我的情况下,请求类型错误。我正在使用GET(dumb)它必须是PUT。

答案 16 :(得分:0)

完整的 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();

答案 17 :(得分:0)

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

在AWS方面

我假设您已经

  1. 创建了一个s3-bucket
  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"

答案 18 :(得分: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
});

答案 19 :(得分:0)

基本上,该错误是因为我使用的是旧版本的aws-sdk,并且我更新了版本,因此发生了此错误。

在我使用节点js的情况下,我在像这样的parmas对象中使用signatureVersion

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'
});

答案 20 :(得分:0)

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

AWS_S3_SIGNATURE_VERSION = "s3v4"

settings.py