Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Amazon S3 - Failed to load resource: the server responded with a status of 403 (Forbidden)

This is the first time I use Amazon S3. I've read questions and answers. They all seem similar to this problem but none of the answers fixed it for me.

I can successfully upload pictures but I can get them to display them (403 forbidden status).

This is the bucket's policy:

{
"Version": "2012-10-17",
"Id": "Policy1475848347662",
"Statement": [
    {
        "Sid": "Stmt1475848335256",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::235314345576:user/userx"
        },
        "Action": [
            "s3:*"
        ],
        "Resource": "arn:aws:s3:::bucketdev/*"
    }
]}

This is the CORS config:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>

This is the user's policy:

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Action": [
            "s3:ListAllMyBuckets",
            "s3:ListBucket",
            "s3:ListBucketVersions",
            "s3:GetObject",
            "s3:ListBucketMultipartUploads"
        ],
        "Resource": [
            "arn:aws:s3:::*"
        ]
    }
]}

Using this component: https://www.npmjs.com/package/react-dropzone-s3-uploader.

Can anyone help?

Thanks.

like image 545
Hideya Avatar asked Oct 19 '22 00:10

Hideya


1 Answers

There are two things to note:

  • Where to assign permissions for access to Amazon S3
  • Which permissions to assign

Where to assign permissions for access to Amazon S3

Objects in Amazon S3 are private by default. There are three ways to assign permission to access objects:

  • Object ACLs (Access Control Lists): These are permissions on the objects themselves
  • Bucket Policies: This is a set of rules applied to the bucket as a whole, but it can also specify permissions related to a subset of a bucket (eg a particular path within the bucket)
  • IAM Policies that are applied to IAM Users, Groups or Roles: These permissions apply specifically to those entities

If your intention is to keep the content of the S3 bucket private but allow access to a specific user, then you should assign permissions to the IAM User (as you have done). It also means that you do not require a Bucket Policy since granting access via any one of the above methods is sufficient.

See documentation: Guidelines for Using the Available Access Policy Options

Also a CORS Policy is only required if a HTML page served from one domain is referring to content from another domain. It is quite possible that you do not require the CORS Policy -- do some testing to confirm whether this is the case.

Which permissions to assign

This is always confusing... Some permissions are associated with the Bucket, while some permissions are associated with the contents of the Bucket.

The following permissions from your policy should be at the Bucket level (arn:aws:s3:::MyBucket):

  • s3:CreateBucket
  • s3:DeleteBucket
  • s3:DeleteBucketPolicy
  • s3:GetBucketPolicy
  • s3:GetLifecycleConfiguration
  • s3:ListBucket
  • s3:ListBucketMultipartUploads
  • s3:PutBucketPolicy
  • s3:PutLifecycleConfiguration

Other API calls (eg GetObject) should be at the object-level (eg arn:aws:s3:::MyBucket/*).

See: Specifying Permissions in a Policy

Therefore, the policy associated with your IAM User should look more like this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1",
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "s3:ListBucketVersions",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "arn:aws:s3:::MY-BUCKET"
            ]
        },
        {
            "Sid": "Stmt2",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::MY-BUCKET/*"
            ]
        }
    ]
}

This grants GetObject permission to objects within the bucket, rather than on the bucket itself.

like image 63
John Rotenstein Avatar answered Nov 11 '22 11:11

John Rotenstein