简体   繁体   中英

Upload to S3 via CloudFront results in 403

I'm trying to sign a URL to upload to S3 via CloudFront.

  • S3 has a bucket policy setup
  • CloudFront is using a custom domain/cert
  • CloudFront is configured to forward headers
  • Signed URLs for GET are working

If I sign a URL with a Policy:

https://staging.*SNIP*.io/341-a25e82ef-8210-49bc-9fbd-b3f0c4807080-original.jpg?Policy=*SNIP*&Signature=*SNIP*&Key-Pair-Id=*SNIP*

Or without the Policy but using an Expires

https://staging.*SNIP*.io/343-aa3e9a57-4d85-4c90-bf05-3d6fdac04a49-original.jpg?Expires=1457765627&Signature=*SNIP*&Key-Pair-Id=*SNIP*

I consistency get:

<Error>
    <Code>AccessDenied</Code>
    <Message>Query-string authentication requires the Signature, Expires and AWSAccessKeyId parameters</Message>
    <RequestId>*snip*</RequestId>
    <HostId>*snip*</HostId>
</Error>

I've rolled my own signing based on various different SO answers. I've tried using the built in signing from AWS SDK. I've destroyed and recreated the CloudFront distribution.

I've completely run out of ideas to try.

I've probably looked at every single issue on SO about signed urls with cloudfront but nothing has helped. I cannot get past this 403 error.

Edit: Seems AWS has no idea why it's not working, it all appears to be configured correctly.

I managed to figure this out. The documentation (at the time of writing this) confused me. Basically:

1) The Cloudfront Distribution needs to be set to restrict access to bucket. (If this isn't done it doesn't seem to pass the auth headers to S3)

2) Hash the payload

3) Sign the Cloudfront URL

4) Sign the request

To hash the payload I used Crypto.js (Core & SHA256)

var reader = new FileReader();

reader.onload = function(readerEvt) {
    var binaryString = readerEvt.target.result;
    var wordArray = arrayBufferToWordArray(binaryString);
    var hash = CryptoJS.SHA256(wordArray);

    var hashedPayload = hash.toString(CryptoJS.enc.Hex);

    // send the hashed payload serverside for use in calculating the signed request
};

reader.readAsArrayBuffer(file);

And to sign the request I followed:

http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html

(comment if you need more information)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM