Finn
Finn

Reputation: 163

Django cant access S3 bucket unless policy completely open to public

I am attempting to use an AWS S3 bucket for static and media files. I am able to get files to the bucket with "python manage.py collectstatic" with the IAM user credentials set in the settings.py file. However, I am not able to access files in the bucket unless I set a bucket policy that is completely open to the public - as below:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucketname/*"
        }
    ]
}

If I set the policy to only specifically allow an IAM user (below), I get "access forbidden errors."

{
    "Version": "2012-10-17",
    "Id": "ExamplePolicy01",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::499213337707:user/bucketusername"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetBucketLocation",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::bucketname/*"
            ]
        }
    ]
}

I have double checked to make sure my IAM access key and secret key are correct. How can I fix this so that only connections with the correct credentials can access the bucket?

relevant settings.py:

#S3 Bucket config
AWS_ACCESS_KEY_ID = 'Key ID here'

AWS_SECRET_ACCESS_KEY = 'secret key here'
AWS_STORAGE_BUCKET_NAME = 'bucketname'
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'


#AWS S3 Settings
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

AWS_LOCATION = 'static'
STATICfILES_DIRs = [
    str(BASE_DIR.joinpath('static')),
]
STATIC_ROOT = BASE_DIR / "static"
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{AWS_LOCATION}/'


STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    # other finders..
    'compressor.finders.CompressorFinder',
)

MEDIA_URL = '//%s.s3.amazonaws.com/media/' % AWS_STORAGE_BUCKET_NAME
MEDIA_ROOT = MEDIA_URL
AWS_QUERYSTRING_AUTH = False # needed for ckeditor with S3
AWS_DEFAULT_ACL = 'public-read'

Upvotes: 0

Views: 565

Answers (1)

Mahmoud Nasser
Mahmoud Nasser

Reputation: 850

Good questions! I made a search on this topic but turns out that we need to make the media and the static files to be public only for Read and GET for example a Facebook profile picture is media right? but it is public so the browser could serve it also if you inspect the profile section an get the link and try to access it outside facebook it would work making the S3 private for read and get will make the resources invasible for the browser or the mobile app. I hope I make it clear to you.

Upvotes: 0

Related Questions