7

I have an S3 Fine Uploader implementation working great. By default, it uploads files fine but they are private. Based on FineUploader's documentation I added the objectProperties option as follows to my client-side js config for FineUploader to make the files public:

    objectProperties: {
        acl: "public-read"
    },

However I now get an access denied response from s3 during upload:

<Error><Code>AccessDenied</Code><Message>Access Denied</Message>
<RequestId>(removed)</RequestId>
<HostId>(removed)</HostId>
</Error>

If it helps, this is my CORS Bucket Policy:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <ExposeHeader>ETag</ExposeHeader>
        <AllowedHeader>content-type</AllowedHeader>
        <AllowedHeader>origin</AllowedHeader>
        <AllowedHeader>x-amz-acl</AllowedHeader>
        <AllowedHeader>x-amz-meta-qqfilename</AllowedHeader>
        <AllowedHeader>x-amz-date</AllowedHeader>
        <AllowedHeader>authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

This is the raw HTTP dump of the request:

Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Connection:keep-alive
Content-Length:39643
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryR70e49pqaNEGSsT1
Host:quickfunnel.s3.amazonaws.com
Origin:http://mysite.local
Referer:http://mysite.local/dashboard/
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Request Payload
------WebKitFormBoundaryR70e49pqaNEGSsT1
Content-Disposition: form-data; name="key"

d50e0c4f-1886-48bb-b077-075fca79b6dc.JPG
------WebKitFormBoundaryR70e49pqaNEGSsT1
Content-Disposition: form-data; name="AWSAccessKeyId"

ACCESS-KEY-REMOVED
------WebKitFormBoundaryR70e49pqaNEGSsT1
Content-Disposition: form-data; name="Content-Type"

image/jpeg
------WebKitFormBoundaryR70e49pqaNEGSsT1
Content-Disposition: form-data; name="success_action_status"

200
------WebKitFormBoundaryR70e49pqaNEGSsT1
Content-Disposition: form-data; name="acl"

public-read
------WebKitFormBoundaryR70e49pqaNEGSsT1
Content-Disposition: form-data; name="x-amz-meta-qfclientid"

1
------WebKitFormBoundaryR70e49pqaNEGSsT1
Content-Disposition: form-data; name="x-amz-meta-qqfilename"

Capture.JPG
------WebKitFormBoundaryR70e49pqaNEGSsT1
Content-Disposition: form-data; name="policy"

eyJleHBpcmF0aW9uIjoiMjAxNC0wMS0wMlQyMzo0MzoxMC4wNDVaIiwiY29uZGl0aW9ucyI6W3siYWNsIjoicHVibGljLXJlYWQifSx7ImJ1Y2tldCI6InF1aWNrZnVubmVsIn0seyJDb250ZW50LVR5cGUiOiJpbWFnZS9qcGVnIn0seyJzdWNjZXNzX2FjdGlvbl9zdGF0dXMiOiIyMDAifSx7ImtleSI6ImQ1MGUwYzRmLTE4ODYtNDhiYi1iMDc3LTA3NWZjYTc5YjZkYy5KUEcifSx7IngtYW16LW1ldGEtcWZjbGllbnRpZCI6IjEifSx7IngtYW16LW1ldGEtcXFmaWxlbmFtZSI6IkNhcHR1cmUuSlBHIn0sWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIjAiLCIxNTAwMDAwMCJdXX0=
------WebKitFormBoundaryR70e49pqaNEGSsT1
Content-Disposition: form-data; name="signature"

K7FC4Toe/xmr0SKGOTy6NG+morw=
------WebKitFormBoundaryR70e49pqaNEGSsT1
Content-Disposition: form-data; name="file"; filename="Capture.JPG"
Content-Type: image/jpeg


------WebKitFormBoundaryR70e49pqaNEGSsT1--
Chris Webb
  • 752
  • 7
  • 22
  • I'm assuming you're trying to view/download the uploaded file. Does: `http://mybucket.s3.amazonaws.com/objectkey` work? (obviously, replacing `mybucket` and `objectkey` with their respective values) – Mark Feltner Jan 03 '14 at 01:47
  • Which specific request results in this error? – Ray Nicholus Jan 03 '14 at 01:47
  • Mark - this error is on uploading with the canned ACL value set. Without that property the upload is fine but the file is "private" within S3 – Chris Webb Jan 03 '14 at 01:58
  • Which specific request results in the error? You'll need to share the client side logs with the debug option set to true if you are not sure how to pinpoint the request . – Ray Nicholus Jan 03 '14 at 01:59
  • Ray - I've added the HTTP dump from Chrome of the request – Chris Webb Jan 03 '14 at 02:04

1 Answers1

21

Most likely, you have not properly configured your client-side IAM group. In order to deviate from the default ACL of "private", the IAM group associated with the request must be able to perform that "s3:PutObjectAcl" action. You'll need to ensure the IAM group associated with your client-side keys has this permission.

Ray Nicholus
  • 19,538
  • 14
  • 59
  • 82
  • 1
    Sounds like the right approach - the documentation only had s3:PutObject - I'll reconfigure and report back. Thanks Ray – Chris Webb Jan 03 '14 at 02:18
  • 1
    great worked a charm thanks Ray. The IAM policy document in case anyone else needs it: { "Version":"2012-10-17", "Statement":[{ "Effect":"Allow", "Action":"s3:PutObject", "Resource":"arn:aws:s3:::yourbucket/*" }, { "Effect":"Allow", "Action":"s3:PutObjectAcl", "Resource":"arn:aws:s3:::yourbucket/*" }] } – Chris Webb Jan 03 '14 at 02:25
  • 4
    Actually, it can be simplified to: `{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:PutObject", "s3:PutObjectAcl" ], "Resource": [ "arn:aws:s3:::yourbucket/*" ], "Effect": "Allow" } ] }` – Ray Nicholus Jan 03 '14 at 02:34