【问题标题】:AWS PHP SDK 3.36 GetObject method throwing SignatureDoesNotMatch errorAWS PHP SDK 3.36 GetObject 方法抛出 SignatureDoesNotMatch 错误
【发布时间】:2017-11-16 01:03:01
【问题描述】:

我们目前无法使用 AWS PHP SDK v. 3.36 从 S3 下载对象。通过 GetObject 方法。

我们看到以下错误:

Error executing "GetObject" on "<object path>";
AWS HTTP error: Client error: `GET <object path>` resulted in a `403 Forbidden` response:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>SignatureDoesNotMatch</Code>
  <Message>The request signature we calcul (truncated...)  SignatureDoesNotMatch (client): The request signature we calculated does not match the signature you
    provided. Check your key and signing method.
    - <?xml version="1.0" encoding="UTF-8"?>
      <Error>
        <Code>SignatureDoesNotMatch</Code>
        <Message>The request signature we calculated does not match the signature you provided.
          Check your key and signing method.

<remaining message redacted>

S3 客户端设置:

public function __construct($key, $secret, $region='us-east-1') {
    $this->key = $key;
    $this->secret = $secret;
    $this->handler = new S3Client([
        'credentials' => [
            'key'    => $key,
            'secret' => $secret
        ],
        'region' =>$region,
        'version' => '2006-03-01'
    ]);
}

调用GetObject方法:

public function getFile($bucket, $sourcefile, $saveToDestination = null) {
    $getarray = array(
        'Bucket' => $bucket,
        'Key' => $sourcefile,
    );

    if ($saveToDestination) {
        $getarray['SaveAs'] = $saveToDestination;
    }

    return $this->handler->getObject($getarray);

}

对于有问题的 IAM 用户,提供了对 S3 的完全访问权限,并且上面使用的凭证已经过验证。

IAM 政策 (AmazonS3FullAccess):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "*"
        }
    ]
}

【问题讨论】:

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


    【解决方案1】:

    事实证明,在 AWS PHP SDK 的 v3 中,如果在提供的存储桶和关键参数之间存在额外的存储桶子路径,则会出现此故障。

    下面的代码被添加到上面调用getFile方法的方法中:

    protected function getS3File($s3_bucket, $s3_key){
    
             /// if the bucket contains additional paths, S3 will choke
             if (strpos($s3_bucket, '/')!==false){
                 $paths = explode('/', $s3_bucket);
                 $s3_bucket = array_shift($paths);
    
                 /// so prepend them to the key!
                 $s3_key=implode('/', $paths) .'/'.$s3_key;
             }
    
             return $this->makeTempFile($this->s3Handler->getFileContents($s3_bucket, $s3_key));
          }
    

    【讨论】:

    • 这就是它应该如何与任何 SDK 的任何版本一起工作。 “key”是完整的路径——不仅仅是文件名。
    • 是的,老实说,我自己并没有意识到这一点。但是,你活着就是学习!
    【解决方案2】:

    稍微挖掘了一下,发现了this。任何一个: a) api 密钥不正确或

    b) 请求中未提供 Content-Length 标头或

    c) 请求 URI 中的非 UTF-8 编码字符串值。

    希望这会有所帮助。

    【讨论】:

    • 感谢您的建议,但提供的链接会将我带到您的根登录页面。介意换个链接吗?我绝对想通读一遍!
    • 糟糕,现在应该修复了。
    • @JustinFox 如果这确实是错误和解决方案,请标记答案,TY。
    • 我就是这么做的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-04-15
    • 2015-07-06
    • 2016-10-12
    • 1970-01-01
    • 2014-12-31
    • 2018-06-08
    • 2019-01-29
    • 1970-01-01
    相关资源
    最近更新 更多