0

I have an AWS API Gateway resource /foo with a GET method. It has a Lambda integration, which for the purposes of this question simply returns bar. However I want the API to be protected, so I have enabled a Cognito authorizer on GET for /foo. I tested this using the VSCode REST Client (which pays no mind to CORS), and sure enough, I get back an HTTP 401 response if GET /foo is called without the appropriate Authorization header in the request.

I then tested the same things using the Fetch API in a modern browser (which does support CORS) running a test site on localhost. My understanding is that in the context of CORS this is a simple request, in which the browser does not make a preflight OPTIONS request. And indeed I can see from the browser network history that the browser directly attempted to access /foo using HTTP GET. Thus it would seem any discussion of configuring CORS for preflight or for OPTIONS is irrelevant to solving this particular problem (although it might be relevant for configuring more complex requests after simple CORS requests are fixed).

In the context of the browser, my Cognito authorizer returned a 401 HTTP response as it did for the VSCode REST client. However the browser, which understands CORS, blocked the response altogether. That is, my JavaScript fetch call await fetch('https://example.com/foo') did not complete with an HTTP 401, but threw an error: NetworkError when attempting to fetch resource. I can see in the network activity that the HTTP request succeeded as expected, with the HTTP response being 401 as expected, but the browser never allowed my JavaScript code to see that response.

This is all expected behavior to this point. If the site on localhost is allowed to access the API at https://example.com/foo, the browser expects the response from the API to include something like the following. (This question is not about whether * is appropriate or whether something more specific should be added; that is beside the point of this question.)

Access-Control-Allow-Origin: *

Unfortunately as the request never got to my Lambda integration, returning the Access-Control-Allow-Origin: * from my Lambda is out of my control before authorization. This is something the Cognito authorizer needs to return.

I found another question, api gateway endpoint with cognito authorizer cros error?, but this question deals with non-simple CORS requests with OPTIONS, and indeed it's unclear what the question is fundamentally about or what the solution was.

I also followed the instructions at Enable CORS on a resource using the API Gateway console and tried to turn on CORS for /foo in the API Gateway console, but I got two errors:

Failed to update CORS headers on 2 methods
Details
    Added Access-Control-Allow-Origin Method Response Header to GET method.
    Added Access-Control-Allow-Origin Integration Response Header Mapping to GET method.

Now I have an extra OPTIONS method configured in API Gateway for /foo with no authorization configured, but GET seems to be the same as before.

How do I configure an AWS API Gateway Cognito Authorizer to return the correct Access-Control-Allow-Origin CORS for a 401 response to a simple request which does not need a CORS preflight request?

My expectation is that, after configuring the AWS API Gateway Cognito Authorizer to return an Access-Control-Allow-Origin: * header, the JavaScript code running on my test site on localhost will successfully return from await fetch('https://example.com/foo') and return an HTTP 401 rather than throwing a NetworkError exception.

This question is not about how my Lambda integration should return CORS information for simple requests that have authorization information and that have passed the Cognito authorizer. This question is about what CORS information the Cognito authorizer returns before the request ever gets to my Lambda.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.