Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add API Gateway custom authorizers in an AWS SAM template?

I'm working on some serverless applications and am looking to do all of the deployments using AWS SAM. I'm not finding a lot of information on how to include custom authorizers for my endpoints. There are some (year old) posts that talk about defining them in Swagger (which I'm not using) or Cloudformation.

Does anyone have an example of either of these methods, or know how to define the custom authorizer in the SAM template?

like image 811
Bryson Tyrrell Avatar asked Feb 04 '23 03:02

Bryson Tyrrell


1 Answers

UPDATE: The AWS Serverless Application Model (SAM) now supports defining an API Auth Object as a part of the AWS::Serverless::Api resource:

https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api-auth-object

Auth:
  MyLambdaTokenAuth:
    FunctionPayloadType: TOKEN
    FunctionArn: !GetAtt MyAuthFunction.Arn
    Identity:
      Header: Authorization
      ReauthorizeEvery: 300

Original Answer:

I did eventually get this working using AWS swagger extensions in my template. I have a basic example on my GitHub:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: An example serverless "Hello World" application with a custom authorizer.

Resources:
  ApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      DefinitionBody:
        swagger: 2.0
        info:
          title:
            Ref: AWS::StackName
        securityDefinitions:
          test-authorizer:
            type: apiKey
            name: Authorization
            in: header
            x-amazon-apigateway-authtype: custom
            x-amazon-apigateway-authorizer:
              type: token
              authorizerUri:
                Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${TestAuthorizerFunc.Arn}/invocations
              authorizerResultTtlInSeconds: 5
        paths:
          "/":
            get:
              x-amazon-apigateway-integration:
                httpMethod: post
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloWorld.Arn}/invocations
              responses: {}
              security:
                - test-authorizer: []

  HelloWorld:
    Type: AWS::Serverless::Function
    Properties:
      Handler: lambda_function.lambda_handler
      Runtime: python3.6
      CodeUri: ./HelloWorld
      Events:
        GetApi:
          Type: Api
          Properties:
            Path: /
            Method: get
            RestApiId:
                Ref: ApiGateway

  TestAuthorizerFunc:
    Type: AWS::Serverless::Function
    Properties:
      Handler: lambda_function.lambda_handler
      Runtime: python3.6
      CodeUri: ./TestAuthorizerFunc

  TestAuthorizerFuncPerm:
    Type: AWS::Lambda::Permission
    DependsOn:
      - ApiGateway
      - TestAuthorizerFunc
    Properties:
      Action: lambda:InvokeFunction
      FunctionName:
        Ref: TestAuthorizerFunc
      Principal: apigateway.amazonaws.com

In the API Gateway resource, the YAML of the swagger definition is added under the DefinitionBody key. The custom authorizer is defined as:

securityDefinitions:
  test-authorizer:
    type: apiKey
    name: Authorization
    in: header
    x-amazon-apigateway-authtype: custom
    x-amazon-apigateway-authorizer:
      type: token
      authorizerUri:
        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${TestAuthorizerFunc.Arn}/invocations
      authorizerResultTtlInSeconds: 5  

Then the authorizer is attached in the definition for the path that it will secure:

paths:
  "/":
    get:
      x-amazon-apigateway-integration:
        httpMethod: post
        type: aws_proxy
        uri:
          Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloWorld.Arn}/invocations
      responses: {}
      security:
        - test-authorizer: []

Code for the Lambda functions can be found here:

https://github.com/brysontyrrell/Serverless-Hello-World/tree/master/hello-world

like image 191
Bryson Tyrrell Avatar answered Feb 07 '23 09:02

Bryson Tyrrell