Amazon web services AWS S3-如何修复&x27;我们计算的请求签名与签名';错误?

Amazon web services AWS S3-如何修复&x27;我们计算的请求签名与签名';错误?,amazon-web-services,amazon-s3,aws-php-sdk,Amazon Web Services,Amazon S3,Aws Php Sdk,我已经在网上搜索了两天多了,可能已经浏览了大多数在线记录的场景和解决方法,但到目前为止没有任何效果 我使用的是运行在PHP5.3上的PHPv2.8.7的AWS SDK 我正在尝试使用以下代码连接到我的S3存储桶: // Create a `Aws` object using a configuration file $aws = Aws::factory('config.php'); // Get the client from the service loc

我已经在网上搜索了两天多了,可能已经浏览了大多数在线记录的场景和解决方法,但到目前为止没有任何效果

我使用的是运行在PHP5.3上的PHPv2.8.7的AWS SDK

我正在尝试使用以下代码连接到我的S3存储桶:

// Create a `Aws` object using a configuration file

        $aws = Aws::factory('config.php');

        // Get the client from the service locator by namespace
        $s3Client = $aws->get('s3');

        $bucket = "xxx";
        $keyname = "xxx";

        try {
            $result = $s3Client->putObject(array(
                'Bucket'        =>      $bucket,
                'Key'           =>      $keyname,
                'Body'          =>      'Hello World!'
            ));
            $file_error = false;
        } catch (Exception $e) {
            $file_error = true;
            echo $e->getMessage();
            die();
        }
        //  
我的config.php文件如下所示:

<?php

return array(
    // Bootstrap the configuration file with AWS specific features
    'includes' => array('_aws'),
    'services' => array(
        // All AWS clients extend from 'default_settings'. Here we are
        // overriding 'default_settings' with our default credentials and
        // providing a default region setting.
        'default_settings' => array(
            'params' => array(
                'credentials' => array(
                    'key'    => 'key',
                    'secret' => 'secret'
                )
            )
        )
    )
);

经过两天的调试,我终于发现了问题

我分配给对象的键以句点开始,即
。\images\ABC.jpg
,这导致出现错误


我希望API提供更有意义和相关的错误消息,唉,我希望这能帮助其他人

我使用错误的凭据获得此错误。我想当我最初粘贴它时,有一些看不见的字符。

当我试图复制带有一些UTF8字符的对象时,也遇到了同样的问题。下面是一个JS示例:

var s3 = new AWS.S3();

s3.copyObject({
    Bucket: 'somebucket',
    CopySource: 'path/to/Weird_file_name_ðÓpíu.jpg',
    Key: 'destination/key.jpg',
    ACL: 'authenticated-read'
}, cb);

通过使用
encodeURIComponent()对CopySource进行编码来解决

事实上,在Java中,我也遇到了同样的错误。在花了4个小时调试之后,我发现问题出在S3对象中的元数据中,因为S3文件中的缓存控件存在空间。1.6.*版本允许此空间,但1.11.*版本不允许此空间,因此引发了签名不匹配错误

i有一个类似的错误,但对我来说,这似乎是由于重新使用IAM用户在两个不同的Elastic Beanstalk环境中使用S3造成的。我通过为每个环境创建一个具有相同权限的IAM用户来处理该症状,从而消除了错误。

如果上述其他解决方案都不适用于您,请尝试使用

aws configure
将打开一组选项,询问键、区域和输出格式


希望这有帮助

我刚刚体验了使用带有React Native的AWS SDK将图像上载到S3的过程。结果证明这是由
ContentEncoding
参数引起的


删除该参数“修复”了问题。

在我的例子中,bucketname是错误的,它包含了密钥的第一部分(bucketxxx/keyxxx)-签名没有问题。

在我的例子中,我将S3URL解析为其组件

例如:

Url:    s3://bucket-name/path/to/file
已解析为:

Bucket: bucket-name
Path:   /path/to/file
让路径部分包含前导“/”的请求失败。

在我的例子(python)中,它失败了,因为我在文件中有这两行代码,是从旧代码继承的

http.client.HTTPConnection.\u http\u vsn=10

http.client.HTTPConnection.\u http\u vsn\u str='http/1.0'

另一个可能的问题可能是元数据包含非US-ASCII字符。对我来说,在将值添加到putRequest时,它有助于对值进行URL编码:

request.Metadata.Add(AmzMetaPrefix+“artist”,HttpUtility.UrlEncode(song.artist));
Add(AmzMetaPrefix+“title”,HttpUtility.UrlEncode(song.title));

在使用Debian stretch可用的最新
awscli
版本(即1.11.13版)时,我在Docker映像中遇到了这种情况,该映像具有非AWS S3端点

升级到CLI版本1.16.84解决了此问题

要使用基于Debian stretch映像的Dockerfile安装最新版本的CLI,而不是:

RUN apt-get update
RUN apt-get install -y awscli
RUN aws --version
使用:


对我来说,我使用了axios,并且通过Deafolt它发送头

content-type: application/x-www-form-urlencoded
因此,我改为发送:

content-type: application/octet-stream
还必须将此内容类型添加到AWS签名中

const params = {
    Bucket: bucket,
    Key: key,
    Expires: expires,
    ContentType = 'application/octet-stream'
}

const s3 = new AWS.S3()
s3.getSignedUrl('putObject', params)

在早期版本的aws php sdk中,在弃用
S3Client::factory()
方法之前,允许您将部分文件路径或中调用的
Key
放置在bucket参数上。我在生产中使用了一个文件管理器,使用v2sdk。由于factory方法仍然有效,因此在更新到
~3.70.0
后,我没有重新访问此模块。今天,我花了两个小时的大部分时间调试为什么我开始收到这个错误,结果是由于我传递的参数(过去是有效的):

我必须将bucket/key路径的
catsinhats
部分移动到
key
参数,如下所示:

$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
    'Bucket' => 'awesomecatpictures',
    'Key' => 'catsinhats/whitecats/white_cat_in_hat1.png',
    'SourceFile' => '/tmp/asdf1234'
]);
我认为正在发生的是,
Bucket
名称现在正在进行URL编码。在进一步检查我从SDK收到的确切消息后,我发现:

https://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.png

AWS HTTP错误:客户端错误:
PUThttps://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.png
导致
403禁止

这表明我提供给我的
Bucket
参数的
/
已经通过
urlencode()
,现在是
%2F

签名的工作方式相当复杂,但问题归结为桶和密钥用于生成加密签名。如果它们在调用客户端和AWS中都不完全匹配,则请求将被403拒绝。错误消息实际上指出了问题:

我们计算的请求签名与您的签名不匹配 提供检查您的密钥和签名方法。


因此,我的
是错误的,因为我的
Bucket
是错误的。

我不知道是否有人在尝试在浏览器中测试输出的URL时遇到此问题,但如果您使用
邮递员
并尝试从
原始
选项卡复制AWS生成的URL,由于逃避反斜杠,您将得到上述错误

使用
Pretty
选项卡复制并粘贴url,以查看它是否实际工作

我最近遇到了这个问题,这个解决方案解决了我的问题。这是为了测试,看看你是否真的检索到了数据
$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
    'Bucket' => 'awesomecatpictures/catsinhats',
    'Key' => 'whitecats/white_cat_in_hat1.png',
    'SourceFile' => '/tmp/asdf1234'
]);
$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
    'Bucket' => 'awesomecatpictures',
    'Key' => 'catsinhats/whitecats/white_cat_in_hat1.png',
    'SourceFile' => '/tmp/asdf1234'
]);
const s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  signatureVersion: 'v4',
});
CopyObjectRequest objectRequest = CopyObjectRequest.builder()
                .copySource(URLEncoder.encode(bucket + "/" + oldFileKey, "UTF-8"))
                .destinationBucket(bucket)
                .destinationKey(newFileKey)
                .build();
s3 = boto3.client(
   's3',
   aws_access_key_id='AKIAIO5FODNN7EXAMPLE',
   aws_secret_access_key='ABCDEF+c2L7yXeGvUyrPgYsDnWRRC1AYEXAMPLE',
   config=Config(signature_version='s3v4')
)