简体   繁体   中英

AWS Cloudfront returning 403 from api request to S3 bucket

I'm working on an amplify react app. From within the app, I poll an S3 bucket that I expect to be populated after a couple of minutes. For clarity the flow would be:

  1. A user uploads a text file to S3 and the app gets the file url in the response
  2. The app then sends a request to aws api-gateway with the S3 bucket uri, which triggers a lambda that then calls aws textract , which in turn triggers a second lambda which writes to an S3 bucket . The first lambda returns a jobId to the app.
  3. The app will then POLL an S3 bucket in order to get the response file using the jobId and display that file to the user.

Initially when polling the bucket, I would use the results bucket url in my api call. This works fine when running the app locally, as the bucket url uses the http protocol, returning a status code 404 until the file is created.

I then created a cloudfront distribution for the app, and the polling request return the error: xhr.js:178 Mixed Content: The page at '<>my cloudfront url>' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '<my endpoint>'. This request has been blocked; the content must be served over HTTPS. xhr.js:178 Mixed Content: The page at '<>my cloudfront url>' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '<my endpoint>'. This request has been blocked; the content must be served over HTTPS. which makes perfect sense.

However changing the viewer protocol behaviour in the app's cloudfront distribution from Redirect HTTP to HTTPS to HTTP and HTTPS didn't seem to work.

So I thought I could create a second cloudfront distribution for the S3 results bucket as that uses https . Yet, when I now run the api call, I get a 403 status code and no longer the 404 . So I tried setting up a custom error response, mapping the 403 error to 404 . I waited a good while as cloudfront can take some time, but this still doesn't seem to have made any difference. Changing the code in my app to expect a 403 instead of a 404 works and after a while once the file has been written to the results S3 bucket I get the file and display it on the app. But I don't want to expect a 403 as this is entirely the wrong code for something that doesn't exist.

I have a several questions here:

  1. Is this the correct approach (having a cloudfront distribution for the results S3 bucket )?
  2. Why would I get a 403 when using the cloudfront url instead of the 404 I was getting when using the S3 results url?
  3. If point 1 is the correct approach, what do I do to fix point 2?

So the solution seems to be, not defining the special error responses, but actually changing the S3 bucket access policy, as described here .

My bucket policy was initially:

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

I then updated it to:

 { "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject" ], "Resource": "arn:aws:s3:::my-results/*" }, { "Sid": "PublicListBucket", "Effect": "Allow", "Principal": "*", "Action": [ "s3:ListBucket" ], "Resource": "arn:aws:s3:::my-results" } ] }

This seemed to solve my issue. However it doesn't seem to explain why I would get a 404 before using cloudfront and then a 403 when using cloudfront.

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