114
I’m using Amazon IAM for the particular key ID and access key and just bumped into the same 403 Forbidden… Turns out you need to give permissions that target both the bucket root and its subobjects:
{
"Statement": [
{
"Principal": {
"AWS": "*"
},
"Effect": "Allow",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::bucket-name/*", "arn:aws:s3:::bucket-name"]
}
]
}
51
I would recommend that you try to test your AWS credentials separately to verify whether the credentials do actually have permission to read and write data to the S3 bucket. The following should work:
>>> import boto
>>> s3 = boto.connect_s3('<access_key>', '<secret_key>')
>>> bucket = s3.lookup('donebox-static')
>>> key = bucket.new_key('testkey')
>>> key.set_contents_from_string('This is a test')
>>> key.exists()
>>> key.delete()
You should try the same test with the other bucket (‘donebox-media’). If this works, the permissions are correct and the problem lies in the Django storages code or configuration. If this fails with a 403 then either:
- The access_key/secret_key strings are incorrect
- The access_key/secret_key are correct but that account doesn’t have the necessary permissions to write to the bucket
I hope that helps. Please report back your findings.
- [Django]-How do you change the collation type for a MySQL column?
- [Django]-What is "load url from future" in Django
- [Django]-Python + Django page redirect
46
I had the same problem and finally discovered that the real problem was the SERVER TIME.
It was misconfigured and AWS responds with a 403 FORBIDDEN.
Using Debian you can autoconfigure using NTP:
ntpdate 0.pool.ntp.org
- [Django]-Reference list item by index within Django template?
- [Django]-Django.db.utils.ProgrammingError: relation already exists
- [Django]-How do I get user IP address in Django?
- [Django]-How to get the current url namespace using Django?
- [Django]-How to make an auto-filled and auto-incrementing field in django admin
- [Django]-How to access request body when using Django Rest Framework and avoid getting RawPostDataException
3
In case this helps anyone, I had to add the following configuration entry for collectstatic
to work and not return 403:
AWS_DEFAULT_ACL = ''
- [Django]-Easiest way to rename a model using Django/South?
- [Django]-How to limit the maximum value of a numeric field in a Django model?
- [Django]-Django logging of custom management commands
3
It is also possible that the wrong credentials are being used. To verify:
import boto
s3 = boto.connect_s3('<your access key>', '<your secret key>')
bucket = s3.get_bucket('<your bucket>') # does this work?
s3 = boto.connect_s3()
s3.aws_access_key_id # is the same key being used by default?
If not, take a look at ~/.boto
, ~/.aws/config
and ~/.aws/credentials
.
- [Django]-Where is a good place to work on accounts/profile in Django with the Django registration app?
- [Django]-Django datefield filter by weekday/weekend
- [Django]-Altering database tables in Django
1
Here is a refinement with minimal permissions.
In all cases, as discussed elsewhere s3:ListAllMyBuckets
is necessary on all buckets.
In it’s default configuration django-storages will upload files to S3 with public-read permissions – see django-storages Amazon S3 backend
Trial and error revealed that in this default configuration the only two permissions required are s3:PutObject
to upload a file in the first place and s3:PutObjectAcl
to set the permissions for that object to public.
No additional actions are required because from that point forward read is public on the object anyway.
IAM User Policy – public-read (default):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::bucketname/*"
}
]
}
It is not always desirable to have objects publicly readable. This is achieved by setting the relevant property in the settings file.
Django settings.py:
...
AWS_DEFAULT_ACL = "private"
...
And then the s3:PutObjectAcl
is no longer required and the minimal permissions are as follows:
IAM User Policy – private:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::bucketname/*"
}
]
}
- [Django]-How to combine django "prefetch_related" and "values" methods?
- [Django]-Automated django receive hook on server: respond to collectstatic with "yes"
- [Django]-Django: How do I add arbitrary html attributes to input fields on a form?
0
Another solution avoiding custom policies and using AWS predefined policies:
-
Add S3 full access permissions to your S3 user.
- IAM / Users / Permissions and Attach Policy
- Add policy “AmazonS3FullAccess”
- [Django]-How to get value from form field in django framework?
- [Django]-Django – how to unit test a post request using request.FILES
- [Django]-How do I include related model fields using Django Rest Framework?
0
Maybe you actually don’t have access to the bucket you’re trying to lookup/get/create..
Remember: bucket names have to be unique across the entire S3 eco-system, so if you try to access (lookup/get/create) a bucket named ‘test’ you will have no access to it.
- [Django]-Get current user in Model Serializer
- [Django]-Strange PostgreSQL "value too long for type character varying(500)"
- [Django]-Can't connect to local MySQL server through socket '/tmp/mysql.sock