I’m having issues generating signed URLs with CloudFront. Whatever I try, I just get an “Access Denied” response.
I’ve created a distribution in CloudFront, and a CloudFront key pair ID. I’ve downloaded the private and public keys for that key pair ID.
In a simple PHP script, I’m trying the following:
use Aws\CloudFront\CloudFrontClient;
$cloudfront = new CloudFrontClient([
'credentials' => [
'key' => '[redacted]', // Access key ID of IAM user with Administrator policy
'secret' => '[redacted]', // Secret access key of same IAM user
],
'debug' => true,
'region' => 'eu-west-1',
'version' => 'latest',
]);
$expires = strtotime('+6 hours');
$resource = 'https://[redacted].cloudfront.net/mp4/bunny-trailer.mp4';
$url = $cloudfront->getSignedUrl([
'url' => $resource,
'policy' => json_encode([
'Statement' => [
[
'Resource' => $resource,
'Condition' => [
'DateLessThan' => [
'AWS:EpochTime' => $expires,
],
],
],
],
]),
'expires' => $expires,
'key_pair_id' => '[redacted]', // Access key ID of CloudFront key pair
'private_key' => '[redacted]', // Relative path to pk-[redacted].pem file
]);
But when visiting the generated URL, it just always gives me an error in the browser with a code of “AccessDenied”.
What am I doing wrong?
Discovered what the issue was. The objects in my S3 bucket weren’t publicly-accessible, and I hadn’t added an Origin Access Identity, so CloudFront couldn’t pull the objects from my origin (my S3 bucket) to cache them.
As soon as I added an Origin Access Identity and added it to my S3 bucket’s policy, my objects immediately became accessible through my CloudFront distribution via signed URLs.
Relevant documentation: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html#private-content-creating-oai
Related
I am using the AWS PHP SDK version 3. I am able to create security groups using the API, as well as creating IP Permission rules. What I can't figure out is how give the IP Permissions rule a name.
Here's what I have:
$params =
[
'Description' => 'My Security Group',
'GroupName' => 'my_security_group',
'VpcId' => 'vpc-a9d2h3d7',
'TagSpecifications' => [
[
'ResourceType' => 'security-group',
'Tags' =>
[
['Key' => 'Name', 'Value' => 'My Security Group']
]
]
],
];
$Ec2Client->createSecurityGroup($params);
At this point the group is created
Then I create an IP Permissions rule:
$ip_permissions = [
'GroupName' => 'my_security_group',
'FromPort' => 0,
'ToPort' => 65535,
'IpProtocol' => 'tcp',
'IpRanges' => [['CidrIp' => 'xx.xxx.xx.xxxx/32', 'Description' => 'Main Office']],
];
$Ec2Client->authorizeSecurityGroupIngress($ip_permissions);
Through the AWS Console, I can see that the rule is created, but the Name column is empty. How do I create the Name through the API?
It would be same, by using TagSpecifications. But instead of security-group you need to have security-group-rule:
'TagSpecifications' => [
[
'ResourceType' => 'security-group-rule',
'Tags' =>
[
['Key' => 'Name', 'Value' => 'My Security Group Rule']
]
]
]
Full example in AWS CLI (don't have php):
aws ec2 authorize-security-group-ingress --group-id sg-00102bde0b55e29fe --ip-permissions FromPort=0,IpProtocol=tcp,IpRanges='[{CidrIp=10.10.10.10/32,Description="Main Office"}]',ToPort=65535 --tag-specifications ResourceType=security-group-rule,Tags='[{Key=Name,Value=MyName}]'
I am trying to list the contents of my S3 bucket. I went through all the configuration steps and created & authenticated a user (I'm using Amplify). For record
Auth.currentCredentials(); gives
Object {
"accessKeyId": "ASIA6NIS4CMFGX3FWTNF",
"authenticated": true,
"expiration": 2020-10-14T13:30:49.000Z,
"identityId": "eu-west-2:6890ebd2-e3f3-4e1d-9725-9f9218241f60",
"secretAccessKey": "CGZsahSl53ulG9BJqGueM78xlMGhKcOs33UP2GUC",
"sessionToken": "IQoJb3JpZ2luX2VjEIX//////////wEaCWV1LXdlc3QtM ...
}
My code:
async function listObjects() {
Storage.list('s3://amplify-mythirdapp-dev-170201-deployment/',
{
level:'public',
region:'eu-west-2',
bucket:'arn:aws:s3:::amplify-mythirdapp-dev-170201-deployment'
})
.then(result => console.log(result))
.catch(err => console.log(err));
}
Which throws an error: Access point ARN region is empty
If I instead do bucket:amplify-mythirdapp-dev-170201-deployment it just returns Array []
But aws s3api list-objects --bucket amplify-mythirdapp-dev-170201-deployment correctly lists objects
What am I missing?
FYI I've also asked this question at aws-amplify/amplify-js/issues/2828.
i use aws S3 bucket with Symfony 3.4 and when i send file i have this error :
Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4.
I think i need change 'signature_version' to v4 https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_configuration.html#signature-version
But i don't know how
config.yml:
aws:
version: 'lastest'
region: 'eu-west-3'
credentials: false
Sqs:
credentials: "#a_service"
sendFile.php
use Aws\S3\S3Client;
public function __construct(S3Client $s3Client){
$this->s3Client = $s3Client;
}
public function sendFile($dataBase64){
$this->s3Client->putObject([
'Bucket' => $monbucket,
'Key' => $key,
'Body' => $dataBase64,
'ACL' => 'public-read'
]);
}
Bundle version: "aws/aws-sdk-php-symfony": "^2.0",
Sometimes it's necessary to send an email with the reply-to address of another user. For example, if a LinkedIn user sends a connection of theirs a LinkedIn message, it makes sense to send that email from the user that sent the message, so that clicking 'reply' actually replies to the person who sent the message.
Is there a way to do this with Amazon SES?
You can pass ReplyToAddresses parameter in $ses->sendEmail() (documentation PHP V2, assuming other languages and versions will have similar structure, search for it)
$sesClient->sendEmail([
'Source' => 'sender#mail.ru',
'Destination' => 'dummy#clie.nt',
'Message' => [
'Subject' => [
'Data' => 'Spammer attack',
],
'Body' => [
'Html' => [
'Data' => 'Le Attacke!',
],
],
],
'ReplyToAddresses' => [
'reply#ema.il',
'sender#mail.ru',
'dummy#clie.nt',
]
]);
Is it possiple to Connect to an Amazon Elasticsearch with Elastica and the "AWS Account access policy"?
When i use "Allow open access to the domain" it works.
$elasticaClient = new \Elastica\Client([
'connections' => [
[
'transport' => 'Https',
'host' => 'search-xxxxxxxx-zzzzzzzz.us-west-2.es.amazonaws.com',
'port' => '',
'curl' => [
CURLOPT_SSL_VERIFYPEER => false,
],
],
],
]);
But in dont know how to set the "Authorization header requires" when i use the "AWS Account access policy".
I am using the FriendsOfSymfony FOSElasticaBundle for Symfony. I solved that problem using AwsAuthV4 as transport like this:
fos_elastica:
clients:
default:
host: "YOURHOST.eu-west-1.es.amazonaws.com"
port: 9200
transport: "AwsAuthV4"
aws_access_key_id: "YOUR_AWS_KEY"
aws_secret_access_key: "YOUR_AWS_SECRET"
aws_region: "eu-west-1"
This is not implemented yet as it needs more then just setting the headers. Best is to follow the issue here in the Elastica repository for progress: https://github.com/ruflin/Elastica/issues/948