I’m learning AWS and with my limited knowledge of AWS, am I right in saying that If I make pre-signed URLS to Upload and Download from a bucket – which is set to block all public access it should work? I take all my authentication and checks through API gateway, so if a user is able to hit the endpoint that returns a pre-signed URL to upload/download, then they are allowed to do so.
If I’m correct then I am confused to why I’m getting an Access denied
error when I try to upload an image to my bucket (which blocks public access) via a pre-signed URL – it works perfectly when the bucket is set to public?
My Lambda function that creates a pre-signed URL:
const AWS = require('aws-sdk');
AWS.config.update({region: process.env.AWS_REGION});
const s3 = new AWS.S3()
// Main entry point
exports.handler = async (event) => {
const result = await getUploadURL()
// console.log('Result: ' result)
return result;
}
const getUploadURL = async function(){
const randomID = parseInt(Math.random()*10000000000)
const s3Params = {
Bucket: process.env.UploadBucket,
Key: `${randomID}.jpg`,
ContentType: 'image/jpeg',
ACL: 'public-read'
}
console.log('getUploadURL: ', s3Params)
return new Promise((resolve, reject) => {
// Get signed URL
resolve({
"statusCode": 200,
"isBase64Encoded": false
"body": JSON.stringify({
"uploadURL": s3.getSignedUrl('putObject', s3Params),
"photoFilename": `${randomID}.jpg`
})
})
});
}
My python code that get’s pre-signed URL and uses it to upload objects:
def upload_file_new(fileDir):
presignedURL = requests.get('<URL>').json()['uploadURL']
data = open(fileDir, 'rb').read()
result = requests.put(presignedURL, data=data, headers={'Content-type': 'image/jpeg'})
My policy for my lambda function:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::contentsync/*"
}
]
}
Advertisement
Answer
It’s likely that your bucket has Block all public access
turned on. Therefore, you cannot set the ACL of the object to public-read
. The solution is that you can either turn off the Block all public access
or change public-read
to private
.