rubyonjets / jets

Ruby on Jets
http://rubyonjets.com
MIT License
2.6k stars 181 forks source link

Error when using Authenticators and CORS is enabled #465

Closed tlhampton13 closed 1 year ago

tlhampton13 commented 4 years ago

Checklist

My Environment

Software Version
Operating System OSX
Jets 2.3.15
Ruby 2.5.5

Expected Behaviour

I have declared authenticators for individual routes in routes.rb and have CORS enabled in application.rb. The CloudFormation generated for the corresponding API Gateway Methods should set the AuthorizationType and AuthenticatorId for the methods bound to routes with authenticators.

With CORS enabled an extra api gateway method get generated, with *Cors* in the name (e.g. PersonsPersonIdCorsApiMethod). This method should have both the AuthoriztaionType and AuthenticationId set.

If CORS is disabled everything is fine.

Current Behavior

Currently, when CORS is enabled the extra *Cors* api gateway methods set the AuthorizationType, but not the AuthenticationId. This result in a CloudFormation error during deployment stating that an Authenticator must be provided.

Step-by-step reproduction instructions

Code Sample

appication.rb

config.cors = true

routes.rb

get    'persons/:person_id', to: 'persons#show', authorizer: "client#cognito_authorizer"

Excerpt from the generated CloudFormation code, after doing a jet build. Notice that the first method has both AuthorizationType and AuthorizerId, but the second *Cors* method is missing the AuthorizerId.

 PersonsPersonIdShowGetApiMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      ResourceId: !Ref PersonsPersonIdApiResource
      RestApiId: !Ref RestApi
      HttpMethod: GET
      RequestParameters: {}
      AuthorizationType: COGNITO_USER_POOLS
      ApiKeyRequired: 'false'
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ShowLambdaFunction.Arn}/invocations
      MethodResponses: []
      AuthorizerId: !Ref ClientCognitoClientAuthorizerAuthorizer
  PersonsPersonIdCorsApiMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      ResourceId: !Ref PersonsPersonIdApiResource
      RestApiId: !Ref RestApi
      AuthorizationType: cognito_user_pools
      HttpMethod: OPTIONS
      MethodResponses:
      - StatusCode: '200'
        ResponseParameters:
          method.response.header.access-control-allow-origin: 'true'
          method.response.header.access-control-allow-credentials: 'true'
          method.response.header.access-control-allow-methods: 'true'
          method.response.header.access-control-allow-headers: 'true'
        ResponseModels: {}
      RequestParameters: {}
      Integration:
        Type: MOCK
        RequestTemplates:
          application/json: "{statusCode:200}"
        IntegrationResponses:
        - StatusCode: '200'
          ResponseParameters:
            method.response.header.access-control-allow-origin: "'*'"
            method.response.header.access-control-allow-credentials: "'true'"
            method.response.header.access-control-allow-methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
            method.response.header.access-control-allow-headers: "'Content-Type,X-Amz-Date,Authorization,Auth,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
          ResponseTemplates:
            application/json: ''

Solution Suggestion

When generating the *Cors* api gateway methods (e.g. PersonsPersonIdCorsApiMethod), the AuthentiatorId should also be set.

bolstycjw commented 4 years ago

Can confirm that i am facing the same issue.

https://github.com/tongueroo/jets/blob/7b4dd59527f70188d9d111ad330837dff16403b3/lib/jets/resource/api_gateway/cors.rb#L54

Apparently, the default cors_authorization_type config is nil, which then resolves to the route's authorization type. Managed to work around the issue by setting: config.api.cors_authorization_type = "NONE"

pgib commented 2 years ago

@bolstycjw Thank you for this tip!