serverless-offline: remote Lambda custom authorizer for API Gateway
Asked Answered
J

0

9

I have declared an HTTP Proxy method on my API Gateway resource using CloudFormation syntax (detailed in this earlier post.)

I am trying to attach a custom authorizer, of type "Request", which uses an existing AWS Lambda function. The serverless docs have a decent example of setting up custom authorizers using CloudFormation. Meanwhile, serverless-offline clearly supports (source) request-scoped custom authorizers.

I have closely cross-referenced the relevant AWS CloudFormation documentation for AWS::ApiGateway::Resource and AWS::ApiGateway::Authorizer, together with the related serverless docs, in creating the below serverless template. But so far, I am not getting the expected output or behavior from serverless-offline.

Resources are created without authorizers

When I boot up the below serverless configuration, no authorizers are loaded for my resource. I don't see what is wrong or missing in my serverless.yml file. Do you have any tips? Thanks in advance!

➜  serverless-offline-attempt git:(master) ✗ npm start

> @ start /Users/freen/src/apig/serverless-offline-attempt
> ./node_modules/serverless/bin/serverless offline

Serverless: Starting Offline: dev/us-east-1.

Serverless: Routes defined in resources:
Serverless: ANY /upstream/{proxy*} -> http://upstream.company.cool/{proxy}

Serverless: Offline listening on http://localhost:3000

serverless.yml

The below template file includes the APIG resources and the authorizer configuration.

service: company-apig
provider:
  name: aws
  stage: dev
  runtime: python2.7

plugins:
  - serverless-offline

custom:
  serverless-offline:
    resourceRoutes: true

resources:
  Resources:
    # Parent APIG RestApi
    ApiGatewayRestApi:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Name: company-apig
        Description: 'The main entry point of the APIG'

    # Shared Authorizers
    AuthorizeCompanyJWTAccessToken:
      Type: AWS::ApiGateway::Authorizer
      Properties:
        Name: AuthorizeCompanyJWTAccessToken
        Type: REQUEST
        RestApiId:
          Ref: ApiGatewayRestApi
        AuthorizerUri: 
          Fn::Join: 
            - ""
            - 
              - "arn:aws:apigateway:"
              - Ref: "AWS::Region"
              - ":lambda:path/2015-03-31/functions/"
              - "arn:aws:lambda:us-east-1:123456789012:function:jwt-tokens-staging-AccessTokenAuthorizer"
              - "/invocations"

    # Resource /upstream
    UpstreamResource:
      Type: AWS::ApiGateway::Resource
      Properties:
        ParentId:
          Fn::GetAtt:
            - ApiGatewayRestApi
            - RootResourceId
        PathPart: 'upstream'
        RestApiId:
          Ref: ApiGatewayRestApi

    # Resource /upstream/{proxy+}
    UpstreamProxyPath:
      Type: AWS::ApiGateway::Resource
      Properties:
        ParentId:
          Ref: UpstreamResource
        PathPart: '{proxy+}'
        RestApiId:
          Ref: ApiGatewayRestApi

    # Method ANY /upstream/{proxy+}
    UpstreamProxyAnyMethod:
      Type: AWS::ApiGateway::Method
      Properties:
        AuthorizationType: CUSTOM
        AuthorizerId:
          Ref: AuthorizeCompanyJWTAccessToken
        HttpMethod: ANY
        Integration:
          IntegrationHttpMethod: ANY
          Type: HTTP_PROXY
          Uri: http://upstream.company.cool/{proxy}
          PassthroughBehavior: WHEN_NO_MATCH
        MethodResponses:
          - StatusCode: 200
        ResourceId:
          Ref: UpstreamProxyPath
        RestApiId:
          Ref: ApiGatewayRestApi

Related:

Jollify answered 13/3, 2019 at 21:58 Comment(2)
Hi Daniel, I'm looking for the same use case. Did you make any progress running an authorizer before the resource route?Hild
Hi Daniel, I'm also looking for the same solution, did you find any solution?Bultman

© 2022 - 2024 — McMap. All rights reserved.