I set up a S3 bucket {bucketName} and an IAM user, {iamUsername}. The user has the following policies to access the bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::{bucketName}",
"arn:aws:s3:::{bucketName}/*"
]
}
]
}
And the bucket has the bucket has the following bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::012345678901:user/iamUsername"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucketName",
"arn:aws:s3:::bucketName/*"
]
}
]
}
Other than this, the bucket blocks all public access as recommended by AWS.
I use the access key of the user to pre-sign the URL to upload a file in Flask:
s3 = boto3.client('s3', aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name=AWS_REGION)
presigned_url = s3.generate_presigned_url(
'put_object',
Params={
'Bucket': S3_BUCKET,
'Key': random_file_name,
'ContentType': file_type
},
ExpiresIn=3600 # URL expires in 1 hour
)
I use this signed url to upload the file in react:
const uploadFile = async (signedUrl) => {
const uploadFormData = new FormData();
uploadFormData.append('file', selectedFile);
try {
await fetch(signedUrl, {
method: 'PUT',
body: uploadFormData
})
.then(response => {
console.log(response);
if (!response.ok) {
console.log(response);
throw new Error(response);
}
return response.json();
})
This is resulting in a 403, like below:
body: ReadableStream
bodyUsed: false
headers: Headers {}
ok: false
redirected: false
status: 403
statusText: "Forbidden"
type: "cors"
url: "https://{bucketName}.s3.amazonaws.com/{fileName}?AWSAccessKeyId={key}&Signature={signature}&content-type=image%2Fjpeg&Expires=1709497547"
CORS for the bucket have been set as below:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"PUT",
"DELETE",
"HEAD",
"POST"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [],
"MaxAgeSeconds": 3600
}
]
Would appreciate help in figuring out what is wrong with the approach, thanks!
Hi Ranjan,
The CORS configuration for my bucket is:
However, when I try to access it using:
I get 403 forbidden: