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

我得到一个错误 AWS::S3::Errors::InvalidRequest The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.时,我尝试上传文件到 S3桶在新的法兰克福地区。所有与 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)

怎么补救?

谢谢你。

152172 次浏览

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

所有区域都支持 V4,但不支持 US-Standard & sup1; ,许多(但不是所有)其他区域也支持另一个较老的方案签名版本2(“ V2”)。

根据 http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html... 新的 S3地区部署后,2014年1月将只支持 V4。

由于 Frankfurt 是在2014年末引入的,所以它不支持 V2,这个错误表明您正在使用 V2。

Http://docs.aws.amazon.com/amazons3/latest/dev/usingawssdk.html 解释了如何在各种 SDK 中启用 V4,假设您正在使用具有该功能的 SDK。

我推测一些旧版本的 SDK 可能不支持这个选项,所以如果上面没有帮助,您可能需要您正在使用的 SDK 的更新版本。


US Standard是基于 us-east-1区域的 S3区域部署的前称。自从这个答案最初写下来的时候, 亚马逊 S3将美国标准地区重命名为美国东(弗吉尼亚州)地区,以符合 AWS 地区命名惯例对于所有的实际目的来说,这只是命名上的改变。

与 PHP SDK 类似的问题是:

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

重要的是 signatureregion

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

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

JS Sdk 工作。

用节点,尝试

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

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

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

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

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

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

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

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

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

对于 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");

对于 boto3,代码如下:

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

或者

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

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

有时默认版本不会更新。请添加以下命令

AWS_S3_SIGNATURE_VERSION = "s3v4"

settings.py

基本上,这个错误是因为我使用的是 aws-sdk 的旧版本,我更新了这个版本,所以出现了这个错误。

在我使用 node 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'
});

检查您的 AWS S3桶 区域和通过适当的区域在连接请求。

在我的情景中,我已经为 亚太区(孟买)设置了‘ 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);
}

对于 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')
)
AWS_S3_REGION_NAME = "ap-south-1"


AWS_S3_SIGNATURE_VERSION = "s3v4"

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

试试这个组合。

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

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

在我的例子中,请求类型是错误的。我使用 GET (哑)它必须是 PUT。

关于 django/boto3/django-Storage 的超新星答案与我合作:

AWS _ S3 _ RegiION _ NAME = “ ap-south-1”

或者在 boto3版本1.4.4之前:

AWS _ S3 _ RegiION _ NAME = “ ap-south-1”

AWS _ S3 _ SIGNATURE _ VERION = “ s3v4”

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

你可以在以下地方检查 aws 区域: 在这里输入链接描述

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

在 AWS 方面

我想你已经知道了

  1. 创建了一个 s3-bucket
  2. 在 IAM 中创建用户

步骤

  1. 配置 CORS 设置

    您的 bucket > 权限 > 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. 配置访问控制列表

您的 bucket > 权限 > 访问控制列表

让公众进入

附注: 访问控制列表后面应该写 public

  1. 解锁公共访问

你的木桶 > 权限 > 阻止公共存取

编辑并关闭所有选项

如果你在研究姜戈的话,这是个小插曲 将以下代码行添加到项目的 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"


下面是我在 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

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

同样来自: https://simpleisbetterthancomplex.com/tutorial/2017/08/01/how-to-setup-amazon-s3-in-a-django-project.html

对我来说,这就是解决之道:

AWS_S3_REGION_NAME = "eu-central-1"
AWS_S3_ADDRESSING_STYLE = 'virtual'

这需要添加到 Django 项目中的 setings.py 中

使用 PHP SDK 如下所示。

require 'vendor/autoload.php';


use Aws\S3\S3Client;


use Aws\S3\Exception\S3Exception;




$client = S3Client::factory(
array(
'signature' => 'v4',
'region' => 'me-south-1',
'key'    => YOUR_AWS_KEY,
'secret' => YOUR_AWS_SECRET
)
);