Api Gateway requires authentication header in the CORS preflight request

0

Hi,

I'm struggling with a scenario where I have a custom authorizer and CORS settings configured for an REST API that is built with CloudFormation. The main problem is: API Gateway is requiring an custom authorization header in the CORS preflight request, what always results in a CORS error when calling the API from a browser:

Access to XMLHttpRequest at 'https://xxx.execute-api.us-east-1.amazonaws.com/Prod/v1/resources' from origin 'http://domain.amazonaws.com' 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.


Example 1 - without header:
Request:

curl --location --request OPTIONS 'https://xxx.execute-api.us-east-1.amazonaws.com/Prod/v1/resources'  

Response:
Http Status: 401
Body: { "message": "Unauthorized" }

Example 2 - with header:
Request:

curl --location --request OPTIONS 'https://xxx.execute-api.us-east-1.amazonaws.com/Prod/v1/resources' \  
--header 'X-Ivs-Session: <any value>'  

Response:
Http Status: 200
Body: {}
Headers: all cors headers are returned

The API Gateway is built and configured by CloudFormation via SAM CLI. My template is the following:

template.yml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
CrudAPI:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Auth:
DefaultAuthorizer: AuthorizationGatewayAuthorizerFunction
Authorizers:
AuthorizationGatewayAuthorizerFunction:
FunctionPayloadType: REQUEST
FunctionArn: !ImportValue 'v1-AuthorizationGatewayAuthorizer'
Identity:
Headers:
- 'X-Ivs-Session'
ReauthorizeEvery: 0
AuthorizerPayloadFormatVersion: 2.0
EnableSimpleResponses: true
Cors:
AllowHeaders: "''"
AllowMethods: "'OPTIONS,POST,PUT,GET,DELETE'"
AllowOrigin: "'
'"
MaxAge: "'600'"

ResourcesListFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handler/get-all-items.getAllItems
Runtime: nodejs12.x
MemorySize: 128
Timeout: 10
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref ResourcesTable
Environment:
Variables:
RESOURCES_TABLE_NAME: !Ref ResourcesTable
Events:
Api:
Type: Api
Properties:
RestApiId: !Ref CrudAPI
Path: /v1/resources
Method: GET

Other resource declarations omitted.

I've already changed my custom authorizer to allow any OPTIONS request, but the request does not even get to the Authorizer and are just blocked by the API Gateway due to the missing header. So, as the CORS preflight response is different from HTTP status 200, the browser always throws a CORS error.

I've already read the documentation, foruns, guides... but couldn't find what i'm doing wrong.

How to make API Gateway allow CORS's OPTION request without requiring a header?

Edited by: lnazari on Mar 1, 2021 3:06 PM

lnazari
asked 3 years ago2684 views
2 Answers
1

In API Gateway, authorizers can be defined at the method level. The "DefaultAuthorizer" is adding the authorizer to OPTIONS. You should be able to fix this by adding an addition property "AddDefaultAuthorizerToCorsPreflight" set to false. See this thread for more details and an example: https://github.com/aws/serverless-application-model/issues/717#issuecomment-523043093

AWS
answered 3 years ago
0

Thanks Alan, it worked like a charm.

lnazari
answered 3 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions