How to add API Gateway custom authorizers in an AWS SAM template?
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