AWS API Gateway 429 response - no CORS headers - ajax

The 429 responses issued by API Gateway (when lowering the max concurrent requests and exceeding it) do not have the CORS headers, so the ajax request in the browser just throws error without any info that could selectively make it trigger a retry.
Any workaround but for retrying any error in the client app / i.e. any work around to have AWS include the CORS headers in the 429 response? CORS is enabled in API gateway, the OPTIONS method is there and responds the headers, and a lambda responds them itself (proxy integration) - all works well but for the 429.

I had a similar issue that was resolved by this answer. You need to create a custom response for 4** and 5** templates. You can do it manually in the AWS console, like so:
Remember to redeploy the API after changing this.
If API Gateway returns 429 you're probably hitting the limit for Lambda's lambda concurrency (or at least that was in my case). The CORS headers are not being sent to the client, since API Gateway blocks the request before hitting your Lambda.

Related

CORS policy error with AWS API Gateway in React

I am trying to set up an API Gateway to call another lambda function that will upload an image to S3. The feature works well when I am using an app like POSTMAN, however when I run the browser using React I am getting the following error.
Access to fetch at 'https://.../upload' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
In my API Gateway I have the following configuration for that method
Gateway Responses for UserUpload API: default 4XX (not checked), default 5XX (not checked)
Methods: post (checked), options (checked)
Access-Control-Allow-Methods: options, post
Access-Control-Allow-Headers: '*'
Access-Control-Allow-Origin: '*'
This API uses an authorizer, I am using the one provided by Auth0 and have not edited the code at all.
And the function that my authorizer calls returns the response like the below (eg happy path):
exports.handler = async (event) => {
//do data checks and upload to s3
return {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Origin": "*",
},
statusCode: 200,
body: JSON.stringify({ message: "success" }),
};
This is my first time setting up both a lambda function, authorisation provider and API Gateway so I might be missing something obvious. I have also tried added mode: no-cors to my fetch POST requests however they still fail in a very similar way.
From what I can tell by looking at the logs of the authorizer and the lambda function that uploads the images, is that they are not even being called. So it appears the CORS error is with the API Gateway.
I have seen in a few tutorials that in their aws template yaml files they add an option AddDefaultAuthorizerToCorsPreflight as False. I can't see this anywhere in the API Gateway console.
Update: I have tested my function with the custom authoriser turned off and it works. So I know that CORS works for the options method, and for the returned request on the lambda function. It is the custom authoriser that is the problem.
The flow is currently:
Method Request - Auth: my-auth-0-authorizer
Integration Request - Type: Lambda_proxy
Lambda function
Integration response - [greyed out Proxy integrations cannot be configured to transform responses]
Method Response: HTTP Status: Proxy (with Access-Control-Allow-Origin in the response headers)
What do I have to do differently or change to allow my authoriser to respect the CORS config?
Update: After leaving my API Gateway for a day, successful responses are now working (using the flow mentioned above). I am not sure if there was a glitch in the system or there was unexpected occurring but it is now working. I am still getting a CORS issue but now only with bad responses.
The custom authoriser fails by return context.fail("Unauthorized"); and when this occurs my browser gets a CORS error. Do I have to set up special gateway responses for 4XX responses?

AWS API Gateway : CORS and Empty Event Object

I have been struggling with setting up AWS API Gateway to pass Query string parameters to my Lambda function.
If I set to API to use Lambda proxy integration, I get a CORS error at the Web client
[index.html:1 Access to XMLHttpRequest at 'https://g2kza1o79f.execute-api.eu-west-2.amazonaws.com/prod/gettest8' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.]
( - even when I have set the API with CORS enabled.
If I set the API to not use Lambda proxy integration, and CORS enabled, the API call works (no CORS error), but the event object received in my Lambda function is empty( hence no query string parameters).
In both cases I am using the GET method.
I can see in the Method Response Header the Access-Control-Allow-Origin option is present, but cannot access the Integration Response
Question: How can I set-up my API to pass query string parameters through to my Lambda function without getting the CORS error? I will also be wanting to set up APIs for POST requests to other Lambda functions.
I believe it is related to First Enable CORS Then Deploy API.
A good thread could be found here.
API Gateway CORS: no 'Access-Control-Allow-Origin' header

Request to Spring Boot application via Cloudfront fails inexplicably with 403 status

When I navigate to web.mysite.com, a static SPA hosted in S3, it has an iframe which has a src of mysite.com/some/path, which is a Spring Boot MVC application in Elastic Beanstalk. Both are behind Cloudfront distributions for HTTPS. This path is handled in the application with a custom resource resolver. This loads successfully, but inside the iframe content there is a script tag looking for mysite.com/some/path/thatsdifferent, handled by the same resolver.
This second request fails with a 403 and I cannot determine why. Navigating to the failing mysite.com/some/path/thatsdifferent directly in my browser or using postman succeeds with a 200 status. The server is configured to allow requests from web.mysite.com through CORS configuration (and there is no CORS-related error message) and Spring Security is configured to permitAll any requests to /some/** regardless of authentication. There is no response body or error message beyond the header x-cache: Error from cloudfront.
If I navigate to the-beanstalk-env-url.com/some/path, it loads the html and then successfully loads the content from the-beanstalk-env-url.com/some/path/thatsdifferent.
Requests to a few different but similar paths succeed. Going to a path which definitely 100% does not exists returns a 404.
The server logs show that the request is being successfully handled and Cloudfront is returning reasonable responses to the client. Looking at the Cloudfront logs simply reports a 403, without any additional information.
Almost 100% of Cloudfront 403 error articles and questions involve S3, which is not the part which is failing here.
Changing the Cloudfront distribution Allowed Methods from GET, HEAD to GET, HEAD, OPTIONS causes the requests directly to mysite.com/some/path/thatsdifferent to begin failing with invalid CORS request, this was fixed by whitelisting the Accept, Authorization, Host, Origin and Referer headers. This did not fix the underlying error.
Adjusting the logging for org.springframework.security doesn't log any extra information when a failing request occurs, my application security configuration is not what is causing the error.
After replacing Cloudfront with a load balancer on my environment in Route 53, the scenario works as expected, so the problem is definitely in Cloudfront.
The solution was to switch the Cloudfront Origin Protocol policy from HTTP Only to HTTPS Only.
I don't know why this mattered from the script file and not the html file, but I decided to test it out when I discovered that if I tried to connect to the Beanstalk environment URL via https, Chrome was warning me that the certificate being used was setup for the domain that was served by the Cloudfront distribution that was causing trouble.

AWS api gateway - http proxy should take status code from origin

I am currently trying to setup AWS Api Gateway, to proxy to another api, that has fully functional methods, response content, status codes etc. This is fairly simple to setup, but I have noticed that the Api Gateway always returns 200 OK no matter what the origin api responds with.
Fx. if there was a bad request (in the origin api) which results in a error message in JSON and a 400 Bad Request, the Api Gateway will respond with a the exact same error message, but a status code of 200 OK
If I remove all settings from the Message Response in the API Gateway web-interface, I get an internal error in the API Gateway. Can it be true that I have to map all the different status codes from the origin api manually in the Api Gateway?
I would prefer if it was possible to just let the status code (as well as the response, which currently works great) pass through, and not have the Api Gateway touch it in any way.
Proxy integration can be used to achieve this. In this case, it is HTTP Proxy. Lambda Proxy integration can also be used but will need some code logic in lambda. API GW will then return the result as-is.
You are correct that currently when using API Gateway you are required to map all response codes in your integration responses. We have heard this "pass through" request from other customers and we may consider including this in future updates to the service.

SAP Gateway CSRF Protection only works over HTTPS, not over HTTP

Today I faced the problem that (suddenly) the SAP Gateway stopped acceppting CSRF tokens issued by himself.
Checked the network trace, everything is fine. The Client gets a token using GET Method and the HTTP Header
X-CSRF-Token: Fetch
receiving one, followed by an immediate POST request using the received Token and getting a 403 Forbidden status with response Body "CSRF Token could not be verified" (or similar)
By default, the CSRF Protection is only enabled over HTTPS in SAP Netweaver Gateway. How to enable CSRF over HTTP (and why not to do so) is described in the following SAP Note:
1896961 - HTTP/HTTPS Configuration for SAP NetWeaver Gateway
The important bit of the Note:
... set the instance profile parameter login/ticket_only_by_https to 0...

Resources