I am trying to use signed url to upload images to s3 bucket. Following is my bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::12345678:user/myuser",
"arn:aws:iam::12345678:root"
]
},
"Action": [
"s3:List*",
"s3:Put*",
"s3:Get*"
],
"Resource": [
"arn:aws:s3:::myBucket",
"arn:aws:s3:::myBucket/*"
]
}
]
}
I am generating the signed url from the server as follows:
var aws = require('aws-sdk');
aws.config = {
accessKeyId: myAccessKeyId,
secretAccessKey: mySecretAccessKey
};
var s3 = new aws.s3();
s3.getSignedUrl('putObject', {
Bucket: 'myBucket',
Expires: 60*60,
key: 'myKey'
}, function (err, url) {
console.log(url);
});
I get the url. But when I try to put an object I get the following error:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>FXXXXXXXXX</RequestId>
<HostId>fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</HostId>
</Error>
Update 1
Here is myuser's policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::2xxxxxxxxxxx:user/myuser",
"arn:aws:iam::2xxxxxxxxxxx:root"
]
},
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::myBucket",
"arn:aws:s3:::myBucket/*"
]
}
]
}
Update 2 I can upload only when following option is set. I dont understand whats the use of bucket policy if only the manual selection of permission work.
Update 3
The following code works. Now the only problem is the signed url
#!/bin/bash
file="$1"
bucket="mybucket"
resource="/${bucket}/${file}"
contentType="image/png"
dateValue=`date -R`
stringToSign="PUT\n\n${contentType}\n${dateValue}\n${resource}"
s3Key="AKxxxxxxxxxxxxxxxxx"
s3Secret="/Wuxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
signature=`echo -en ${stringToSign} | openssl sha1 -hmac ${s3Secret} -binary | base64`
curl -X PUT -T "${file}" \
-H "Host: ${bucket}.s3.amazonaws.com" \
-H "Date: ${dateValue}" \
-H "Content-Type: ${contentType}" \
-H "Authorization: AWS ${s3Key}:${signature}" \
https://${bucket}.s3.amazonaws.com/${file}
I managed to succesfully upload a file by using your code.
Here are the steps I followed:
Created a new bucket and a new IAM user
Set IAM user's policy as below:
Did NOT create a bucket policy
Used your code to generate the pre-signed URL:
Copied the URL on the screen and used curl to test the upload as below:
In my case it generally took 5-10 seconds for the policy changes to take effect so if it fails the first time make sure to keep sending it for a while.
Hope this helps.
The final page will be like this.
You may also check Security Credentials sub tab, your accessKeyId should be on the list. The secretAccessKey just can not get again.
You've correctly set up the permissions on the bucket, to allow access from the user.
But you also need to edit the policy of the user, to allow the user to access the S3 service.
Edit the IAM policy of the user whose credentials you're using to generate the self-signed URL. Something like this will definitely cover everything:
It may help you too :) Add a ContentType property :