9

In AWS CloudFront I set this within: "Allowed HTTP Methods" in the "Default Cache Behavior Settings" area: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE

My CloudFront is linked to an AWS S3 bucket. So I set the AWS S3 CORS configuration to:

<?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>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

My current AWS S3 bucket policy is:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "AllowPublicRead",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<bucket_name_here>/*"
        }
    ]
}

Unfortunately when run through curl I get:

$ curl -I -s -X POST -H "Origin: www.example.com" [hash_here].cloudfront.net
HTTP/1.1 405 Method Not Allowed
Content-Type: application/xml
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD
Access-Control-Max-Age: 3000
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Allow: GET, DELETE, HEAD, PUT
Date: Sun, 01 Mar 2015 14:12:26 GMT
Server: AmazonS3
X-Cache: Error from cloudfront
Via: 1.1 5896eef8502a96757950c7d389f2015c.cloudfront.net (CloudFront)
X-Amz-Cf-Id: uBK_gStEvSTWypvU8_YYjtfjC2UzdR3Ff_cDLitMaeUBNZ9AgrSkJg==
Samuel Marks
  • 915
  • 9
  • 21
  • From the response you have posted it looks like the error is returned by S3, not CloudFront. Did you properly setup bucket access permissions so CloudFront could POST there? – Alex Z Mar 07 '15 at 00:36
  • I think I did, everything I did is outlined in my question. If I'm missing a step, then point out where and I'll accept the working solution as answer :) – Samuel Marks Mar 07 '15 at 00:51
  • Take a look here: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html#private-content-granting-permissions-to-oai. It talks about permissions to read object, but I think you might need to explicitly enable write permission for Origin Access Identity you use for CloudFront – Alex Z Mar 07 '15 at 01:42
  • Samuel, from I can see you did not set up correct bucket policy for your your be*****-frontend S3 bucket. Currently it allows only public reads, while you need to allow posting to it (http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html). The easiest way to do this automatically would be to set up Origin Access Identity in your CloudFront configuration; CloudFront will automatically add required permissions to your bucket policy. Cheers, your CloudFront team. – Dmitry Guyvoronsky Mar 07 '15 at 02:16
  • Actually @DmitryGuyvoronsky I seem to be approaching this problem incorrectly. I have JavaScript doing GET/POST/PUT/DELETE to a custom REST API on EC2 with failover via ELB. Should I use Route 53 to direct calls to `/api/*` to ELB, and all other paths to CloudFront? - Or should I use CloudFront's "Custom Origins" ([ref](http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html)) to forward onto my `/api/*`? – Samuel Marks Mar 08 '15 at 06:32
  • @SamuelMarks: I think decision is yours, and either approach is fine. You can set up Cache Behaviors so that CloudFront will proxy POST/PUT requests to your origin EC2 server without caching them. This setup has 2 advantages. Firstly, you can use single domain name for your viewers (say, example.com/api is proxied to your EC2 server, while rest of example.com/* is seved as static files from S3 bucket). Secondly, your viewers are likely to have better connection times since CloudFront will try to keep TCP connection open to EC2 and reuse it between viewer requests. – Dmitry Guyvoronsky Mar 12 '15 at 03:57
  • Just to throw another option into the mix, I had my cloudfront distribution pointing at an "Origin Path" (folder from the root of the bucket) to make permissions simpler. This also caused the 405 error and so had to create a new bucket instead. It's the `Allow: GET, DELETE, HEAD, PUT` that gives that away in curl testing. – toxaq Jul 05 '16 at 00:39

1 Answers1

4

It may be too late to answer this question. One of the causes of this issue is the Default Root Object . The POST request must be made to the cloudfront root url ("/"). Check the 'Default Root Object' settings in cloudfront. Its value must be empty, and not index.html.

neerajdngl
  • 190
  • 6
  • That didn't make a difference in my case, unfortunately – Leon Mar 20 '18 at 19:45
  • This did fix my issue. If it isn't the answer for everyone, it is at least something that should be in the checklist. – bts Jun 15 '18 at 14:55