Access Denied for ListObjects AWS STS and S3 Client - php

I am unable to use the method ListObjects to access AWS S3 using the Secure Token Service.
The documentation states a bucket and it's object can be private, while we can use AWS STS to gain temporary credentials to access the S3 objects.
I am attempting to create a Graphics Server. I have a separate service that you can query. During the response, my plan is to use AWS STS to expose the images in my S3 bucket.
use Aws\Sts\StsClient;
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$bucket = 'bucket_name';
// the security credentials that you use to obtain temporary security credentials.
$stsClient = StsClient::factory(array(
'credentials' => array(
'secret' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'key' => 'YYYYYYYYYYYYYYYYYYYYYYYYY'
),
'region'=>'us-east-1',
'version'=>'latest'
));
// Fetch the federated credentials.
$sessionToken = $stsClient->getFederationToken([
'Name' => 'IAM-Username',
'DurationSeconds' => '3600',
'PolicyName' => 'my-policy'
]);
// The following will be part of your less trusted code. You provide temporary
// security credentials so the code can send authenticated requests to Amazon S3.
$s3 = new S3Client([
'region' => 'us-east-1',
'version' => 'latest',
'credentials' => [
'key' => $sessionToken['Credentials']['AccessKeyId'],
'secret' => $sessionToken['Credentials']['SecretAccessKey'],
'token' => $sessionToken['Credentials']['SessionToken']
]
]);
print_r($sessionToken);
echo "<br/>";
echo "<br/>";
try {
$result = $s3->listObjects([
'Bucket' => $bucket
]);
} catch (S3Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
I was expecting a list of S3 Object Keys. But instead I get an error message:
Error executing "ListObjects" on "https://s3.amazonaws.com/bucket_name?encoding-type=url"; AWS HTTP error: Client error: GET
https://s3.amazonaws.com/bucket_name?encoding-type=url resulted in a 403 >Forbidden response: AccessDeniedAccess Denied AccessDenied (client): >Access Denied - AccessDeniedAccess Denied XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

found my answer. I was calling the wrong method.
I changed this:
$sessionToken = $stsClient->getFederationToken([
'Name' => 'IAM-Username',
'DurationSeconds' => '3600',
'PolicyName' => 'my-policy'
]);
to this:
$sessionToken = $stsClient->getSessionToken([
'Name' => 'IAM-Username',
'DurationSeconds' => '3600',
'PolicyName' => 'my-policy'
]);
use getSessionToken instead of getFederationToken, which is kinda obvious.

Related

PHP SDK For AWS S3 Using ARN Bucket for Auth

We're using the latest PHP AWS S3 SDK.
We've been given a ARN Bucket name
eg:
arn:aws:s3:::project-s3-eu-west-2-d-app-uploads
Using the PHP Code, we're trying:
<?php
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
$s3 = new S3Client([
'version' => 'latest',
'region' => 'eu-west-2',
'use_arn_region' => TRUE, // or FALSE
]);
$s3->putObject([
'Bucket' => 'arn:aws:s3:::project-s3-eu-west-2-d-app-uploads',
// 'Bucket' => 'project-s3-eu-west-2-d-app-uploads.s3.eu-west-2.amazonaws.com', // this did not work
'Key' => 'random-unique-name.ext',
'Body' => fopen('/local/file/path/name.ext', 'r'),
'ACL' => ACL_PUBLIC_READ,
]);
?>
But - no matter what we try, we get the following error:
Bucket parameter parsed as ARN and failed with: Provided ARN was not a valid S3 access point ARN or S3 Outposts access point ARN.
Have you used an ARN for auth, not a Key/Secret?
Thanks

The provided token is malformed or otherwise invalid

latestAll S3 bucket file is displayed, but when I upload file then error is generate.
I have ARN and instance profile.
use Aws\Credentials\CredentialProvider;
use Aws\Credentials\InstanceProfileProvider;
use Aws\Credentials\AssumeRoleCredentialProvider;
use Aws\S3\S3Client;
use Aws\Sts\StsClient;
$profile = new InstanceProfileProvider();
$ARN = ""; // MY ARN
$sessionName = "s3-access-example";
$assumeRoleCredentials = new AssumeRoleCredentialProvider([
'client' => new StsClient([
'region' => "ap-east-1",
'version' => "latest",
'credentials' => $profile
]),
'assume_role_params' => [
'RoleArn' => $ARN,
'RoleSessionName' => $sessionName,
],
]);
$provider = CredentialProvider::memoize($assumeRoleCredentials);
$this->s3hd = S3Client::factory([
'credentials' => $provider,
'version' => "latest",
'region' => "ap-east-1"
]);
public function upload($name, $file, $type, $Bucket = false)
{
if (! $Bucket) {
$Bucket = $this->bucket;
}
$result = $this->s3hd->putObject([
'Bucket' => $Bucket,
'Key' => $name,
'SourceFile' => $file,
'ContentType' => $type,
'ACL' => 'public-read'
]);
$this->s3hd->waitUntil('ObjectExists', [
'Bucket' => $Bucket,
'Key' => $name
]);
return $result;
}
Message: Error executing "PutObject" on error file url here; AWS HTTP error: Client error: PUT error file url here resulted in a 400 Bad Request` response: InvalidTokenThe provided token is malformed or other (truncated...) InvalidToken (client): The provided token is malformed or otherwise invalid. - InvalidTokenThe provided token is malformed or otherwise invalid.
In my case. I was trying through CLI.
I configured AWS cli by running
aws configure
Inside ~/.aws/credentials, look for session_token. If you have the session_token. Then update it.
Otherwise remove session_token and try again.
And Voila It worked!
You're getting this error because Hong Kong (ap-east-1) is not enabled by default. You need to enable it in the AWS console if you have the correct permissions, then try again.
See the AWS Docs for instructions on how to do that.
I am using s3cmd and based on the above answer I was able to solve by deleting the .s3cmd file and reconfiguring (s3cmd --configure), which cleared the access_token:
diff .s3cfg previous_s3cmd
< access_token =
---
> access_token = vkp1Jf\etc...
Also increased the chunk sizes:
< recv_chunk = 65536
---
> recv_chunk = 4096
< send_chunk = 65536
---
> send_chunk = 4096
And I guess I had previously opted for https requests, as opposed to the (current) default:
< use_https = True
---
> use_https = False
Success
Success. Your access key and secret key worked fine :-)
Now verifying that encryption works...
Success. Encryption and decryption worked fine :-)

Have a problem with cloudfront signed urls (No account found for the given parameters)

I'm trying to create signed urls from cloudfront with aws-sdk-php
I have created both Distributions WEB and RTMP
and this is the code i used to do that
this is start.php
<?php
require 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\CloudFront\CloudFrontClient;
$config = require('config.php');
// S3
$client = new Aws\S3\S3Client([
'version' => 'latest',
'region' => 'us-east-2',
]);
// CloudFront
$cloudfront = CloudFrontClient::factory([
'version' => 'latest',
'region' => 'us-east-2',
]);
and this is config.php
<?php
return [
's3'=>[
'key' => 'XXXXXXXXXXXXXXXXXXXXXXXXXX',
'secret' => 'XXXXXXXXXXXXXXXXXXXXXXXXXX',
'bucket' => 'hdamovies',
'region' => 'us-east-2',
],
'cloudFront' => [
'url' => 'https://d2t7o0s69hxjwd.cloudfront.net',
],
];
and this is index.php
<?php
require 'config/start.php';
$video = 'XXXXXXXXXXX.mp4';
$expiry = new DateTime( '+1 hour' );
$url = $cloudfront->getSignedUrl([
'private_key' => 'pk-XXXXXXXXXXXXXXXXXXXXX.pem',
'key_pair_id' => 'XXXXXXXXXXXXXXXXXXXXX',
'url' => "{$config['cloudFront']['url']}/{$video}",
'expires' => strtotime('+10 minutes'),
]);
echo "Downlod";
When i click on the link i get that error
<Error>
<Code>KMS.UnrecognizedClientException</Code>
<Message>No account found for the given parameters</Message>
<RequestId>0F0A772FE67F0503</RequestId>
<HostId>juuIQZKHb1pbmiVkP7NVaKSODFYmBtj3T9AfDNZuXslhb++LcBsw9GNjpT0FG8MxgeQGqbVo+bo=</HostId></Error>
What is the problem here and how can i solve that?
CloudFront does not support downloading objects that were stored, encrypted, in S3 using KMS Keys, apparently because the CloudFront Origin Access Identity is not an IAM user, so it's not possible to authorize it to have the necessary access to KMS.
https://forums.aws.amazon.com/thread.jspa?threadID=268390
I had this issue and had it resolved after setting up the correctly Identities. However, I had a lot of issues with the error even after setting things up correctly. This was because I was attempting to download a file that was originally uploaded when the bucket was KMS encrypted, then later when I changed it to SSE-S3, it still was throwing a KMS error.
After reuploading the file, it seemed to work without any issues. Hope this helps someone else

getting error AWS HTTP error: cURL error 6: when creation bucket using 3.52 php sdk

I am using own cloud storage Rados s3 server and trying to create a bucket using 3.52 php AWS sdk. Following is the code I am running in my console:
require 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Credentials\CredentialProvider;
$Connection = new S3Client([
'region' => 'us-west-2',
'version' => 'latest',
'endpoint' => 'http://XXX.XX.XX.XXX',
'credentials' => [
'key' => 'xx',
'secret' => 'XX'
],
]);
//create a bucket
$promise =$Connection->createBucket(array('Bucket' => 'pankaj'));
I am getting below fatal error
Fatal error: Uncaught exception 'Aws\S3\Exception\S3Exception' with message 'Error executing "CreateBucket" on "http://pankaj.XXX.XX.XX.XXX/"; AWS HTTP error: cURL error 6: Could not resolve host: pankaj.XXX.XX.XX.XXX; Name or service not known (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)' in /var/www/html/object/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php on line 191
I think it's not accepting your end point which you define.
please use add this key in your client connection
'use_path_style_endpoint' => true
Example :
$s3Client = new S3Client([
'region' => 'us-west-2',
'version' => '2006-03-01',
'use_path_style_endpoint' => true
]);
Remove the endpoint from the client configuration.
require 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
$BUCKET_NAME='<BUCKET-NAME>';
//Create a S3Client
$s3Client = new S3Client([
'region' => 'us-west-2',
'version' => '2006-03-01'
]);
//Creating S3 Bucket
try {
$result = $s3Client->createBucket([
'Bucket' => $BUCKET_NAME,
]);
}catch (AwsException $e) {
// output error message if fails
echo $e->getMessage();
echo "\n";
}

AWS SDK for PHP - Fatal Error Issue

I am trying to connect to my S3 to upload a file via my server but whenever i try to run the PHP, i encounter the following error below. I included the Version and Region but yet the issue still stands?
Error:
Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Missing required client configuration options: region: (string) A "region" configuration value is required for the "s3" service (e.g., "us-west-2"). A list of available public regions and endpoints can be found at http://docs.aws.amazon.com/general/latest/gr/rande.html. version: (string) A "version" configuration value is required. Specifying a version constraint ensures that your code will not be affected by a breaking change made to the service. For example, when using Amazon S3, you can lock your API version to "2006-03-01". Your build of the SDK has the following version(s) of "s3": * "2006-03-01" You may provide "latest" to the "version" configuration value to utilize the most recent available API version that your client's API provider can find. Note: Using 'latest' in a production application is not recommended. A list of available API versions can be found on each client's API documentation page: http:/ in /srv/http/auploader/include/Aws/ClientResolver.php on line 364
My Code:
<?PHP
require '/srv/http/test/include/aws-autoloader.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$bucket = 'testbucket';
$keyname = 'sample';
// $filepath should be absolute path to a file on disk
$filepath = '/srv/http/testfile/setup.html';
// Instantiate the client.
$s3 = S3Client::factory(array(
'key' => 'blank',
'secret' => 'blank'
));
try {
// Upload data.
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $filepath,
'ACL' => 'public-read',
'Region' => 'eu-west-1',
'Version' => '2006-03-01'
));
// Print the URL to the object.
echo $result['ObjectURL'] . "\n";
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
?>
You have to create an object of S3. And keys you have put is misplaced please do it as following.
$s3 = S3Client::factory([
'version' => 'latest',
'region' => 'eu-west-1',
'credentials' => [
'key' => "your s3 bucket key",
'secret' => "your s3 bucket secret key",
]
]);
By using s3 object you can implement putObject method something like this.
$result = $s3->putObject(array(
'Bucket' => "yourbucket name",
'Key' => $keyName,
'SourceFile' => $filepath,
'ACL' => 'public-read', //for making the public url
'Version' => '2006-03-01'
));
));
Hope it helps!
For SES AWS SDK v3 use
/*
* 1. version as `2010-12-01`
* 2. version as Eg. `us-east-1`.
*/
ini_set("display_errors", 1);
Aws\Ses\SesClient::factory(array(
'credentials' => array(
'key' => "someKey",
'secret' => "someSecret",
),
"region" => "us-east-1",
"version" => "2010-12-01")
);

Categories