AWS S3 access denied when getting image by url

匿名 (未验证) 提交于 2019-12-03 08:33:39

问题:

I am working on AWS EC2 Ubuntu Machine and trying to fetch image from AWS S3 but following error has been shown to me every time.

<Error> <Code>InvalidArgument</Code> <Message> Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4. </Message> <ArgumentName>Authorization</ArgumentName> <ArgumentValue>null</ArgumentValue> <RequestId>7C8B4BF1CE2FDC9E</RequestId> <HostId> /L5kjuOET4XFgGter2eFHX+aRSvVm/7VVmIBqQE/oMLeQZ1ditSMZuHPOlsMaKi8hYRnGilTqZY= </HostId> </Error> 

Here is my bucket policy

{  "Version": "2012-10-17",  "Id": "Policy1441213815928",  "Statement": [   {    "Sid": "Stmt1441213813464",    "Effect": "Allow",    "Principal": "*",    "Action": "s3:GetObject",    "Resource": "arn:aws:s3:::mytest.sample/*"   }  ] } 

Here is the code

require 'aws-autoloader.php';  $credentials = new Aws\Credentials\Credentials('key', 'key'); $bucketName = "mytest.sample"; $s3 = new Aws\S3\S3Client([     'signature' => 'v4',     'version' => 'latest',     'region' => 'ap-southeast-1',     'credentials' => $credentials,     'http' => [         'verify' => '/home/ubuntu/cacert.pem'     ],     'Statement' => [         'Action ' => "*",     ],    ]);  $result = $s3->getObject(array( 'Bucket' => $bucketName, 'Key' => 'about_us.jpg',     )); 

Html

<img src="<?php echo $result['@metadata']['effectiveUri']; ?>" /> 

Edit for Michael - sqlbot : here I am using default KMS.

   try {         $result = $this->Amazon->S3->putObject(array(             'Bucket' => 'mytest.sample',             'ACL' => 'authenticated-read',             'Key' =>  $newfilename,             'ServerSideEncryption' => 'aws:kms',             'SourceFile' => $filepath,             'ContentType' => mime_content_type($filepath),             'debug' => [                 'logfn' => function ($msg) {                     echo $msg . "\n";                 },                 'stream_size' => 0,                 'scrub_auth' => true,                 'http' => true,             ],         ));     } catch (S3Exception $e) {         echo $e->getMessage() . "\n";     } 

let me know if you need more.

回答1:

I have also face this issue with aws:kms encyrption key, I suggest that if you wanted to use kms key then you have to create your kms key in IAM section of AWS Console. I love to recommended AES256 server side encryption, here S3 automatically Encrypted your data while putting and decryption while getting object. Please go through below link: S3 Server Side encryption with AES256

My Solution is change this line 'ServerSideEncryption' => 'aws:kms' with 'ServerSideEncryption' => 'AES256'

 try {     $result = $this->Amazon->S3->putObject(array(         'Bucket' => 'mytest.sample',         'ACL' => 'authenticated-read',         'Key' =>  $newfilename,         'ServerSideEncryption' => 'AES256',         'SourceFile' => $filepath,         'ContentType' => mime_content_type($filepath),         'debug' => [             'logfn' => function ($msg) {                 echo $msg . "\n";             },             'stream_size' => 0,             'scrub_auth' => true,             'http' => true,         ],     )); } catch (S3Exception $e) {     echo $e->getMessage() . "\n"; } 

Please also update your bucket policy with below json, it will prevent you to upload object with out AES256 encryption

{         "Sid": "DenyUnEncryptedObjectUploads",         "Effect": "Deny",         "Principal": "*",         "Action": "s3:PutObject",         "Resource": "arn:aws:s3:::yourbucketname/*",         "Condition": {             "StringNotEquals": {                 "s3:x-amz-server-side-encryption": "AES256"             }         }     } 


回答2:

PHP sdk v2

  1. the Credentials package is Aws\Common\Credentials
  2. to create an S3Client you need a factory

Try something like this

use Aws\S3\S3Client; use Aws\Common\Credentials\Credentials;  $credentials = new Credentials('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY');  // Instantiate the S3 client with your AWS credentials $s3Client = S3Client::factory(array(     'signature' => 'v4',     'region' => 'ap-southeast-1',     'credentials' => $credentials,     .....   ]); ) 

If that does not work you might try to declare explicitly a SignatureV4 object

use Aws\S3\S3Client; use Aws\Common\Credentials\Credentials; use Aws\Common\Signature\SignatureV4;  $credentials = new Credentials('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY');  // Instantiate the S3 client with your AWS credentials $s3Client = S3Client::factory(array(     'signature' => new SignatureV4(),     'region' => 'ap-southeast-1',     'credentials' => $credentials,     .....   ]); ) 

In case you upgrade to sdk v3

  1. You need to have signature_version (instead of signature) as parameter when you declare your s3 client
  2. Statement does not appear to be a valid parameter (http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/configuration.html#signature-version)
  3. if issue you can turn on debug param to get more output

This would look like this

$s3 = new Aws\S3\S3Client([     'signature_version' => 'v4',     'version' => 'latest',     'region' => 'ap-southeast-1',     'credentials' => $credentials,     'http' => [         'verify' => '/home/ubuntu/cacert.pem'     ],     'debug'   => true    ]); 

see here for the full list of available parameter



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!