AWS SAM API with Cognito User Pool Authorizer

How can I create an API with AWS SAM that does authorization using an authorized Cognito User Pools administrator?

Theres AWS :: ApiGateway :: Authorizer . But...

{ "Type" : "AWS::ApiGateway::Authorizer", "Properties" : { "AuthorizerCredentials" : String, "AuthorizerResultTtlInSeconds" : Integer, "AuthorizerUri" : String, "IdentitySource" : String, "IdentityValidationExpression" : String, "Name" : String, "ProviderARNs" : [ String, ... ], "RestApiId" : String, "Type" : String } } 

Does it look like RestApiId refers to the API that this authorizer uses? But with AWS SAM, my APIs are defined as

 Resources: Ec2Index: Type: AWS::Serverless::Function Properties: Handler: ec2/index.handler Runtime: nodejs6.10 CodeUri: ./src FunctionName: 'ApiEc2IndexHandler' Description: 'List EC2 resources' Timeout: 30 Role: 'arn:aws:iam::598545985414:role/awsmanagement-lambda-management' Events: Ec2Index: Type: Api Properties: Path: /ec2 Method: get 

I don’t understand how can I tie them together?

+12
amazon-web-services amazon-cloudformation amazon-cognito
source share
5 answers

I'm not sure that you can specify an authorizer in SAM, but you can embed Swagger in SAM files that can do this. This is a new feature dated February 17th [ link ].

I am definitely not an expert on Swagger or SAM, but it seems like you would like something like:

 AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: Simple API Endpoint configured using Swagger specified inline and backed by a Lambda function Resources: Ec2Index: Type: AWS::Serverless::Api Properties: StageName: <stage> DefinitionBody: swagger: 2.0 info: title: Ref: AWS::StackName securityDefinitions: cognitoUserPool: type: apiKey, name: "Authorization" in: header x-amazon-apigateway-authtype: cognito_user_pools x-amazon-apigateway-authorizer: type: cognito_user_pools providerARNs: - arn:aws:cognito-idp:${AWS::Region}:{AWS::AccountId}:userpool/<user_pool_id> paths: "/ec2": get: security: - cognitoUserPool: [] x-amazon-apigateway-integration: httpMethod: POST type: aws_proxy uri: Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Ec2IndexLamb.Arn}/invocations responses: {} swagger: '2.0' Ec2IndexLamb: Type: AWS::Serverless::Function Properties: Handler: ec2/index.handler Runtime: nodejs6.10 CodeUri: ./src FunctionName: 'ApiEc2IndexHandler' Description: 'List EC2 resources' Timeout: 30 Role: 'arn:aws:iam::598545985414:role/awsmanagement-lambda-management' Events: Ec2Index: Type: Api Properties: Path: /ec2 Method: get 

Recommendations:

https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html#apigateway-enable-cognito-user-pool

https://github.com/awslabs/serverless-application-model/blob/master/examples/2016-10-31/inline_swagger/template.yaml


Edit: Swagger 2.0 syntax for the "security" section has been fixed, this should be a list.

+2
source share

Now you can reference the implicitly created API gateway using "ServerlessRestApi". So in your SAM template add this piece of regular Cloudformation, and everything will work fine

 ApiCognitoAuthorizer: Type: AWS::ApiGateway::Authorizer Properties: IdentitySource: 'method.request.header.Authorization' Name: ApiCognitoAuthorizer ProviderARNs: - 'arn:aws:cognito-idp:{region}:{userpoolIdentifier}' RestApiId: !Ref ServerlessRestApi Type: COGNITO_USER_POOLS 
+1
source share

You can add your Cognito User Authorizer directly to SAM AWS::Serverless::Api .

  MyApi: Type: AWS::Serverless::Api Properties: StageName: Prod Cors: "'*'" Auth: DefaultAuthorizer: MyCognitoAuthorizer Authorizers: MyCognitoAuthorizer: UserPoolArn: 'arn:aws:cognito-.....' # YOUR COGNITO USER POOL ARN 

and in your AWS::Serverless::Function you can add a function authorizer if you have not set it by default. Or you can disable it using Authorizer: 'NONE' .

 Auth: Authorizer: MyCognitoAuthorizer 

see also documentation .

+1
source share

As mentioned in @simones, the following will create the Cognito User Pool authorizer (CF template).

 ApiCognitoAuthorizer: Type: AWS::ApiGateway::Authorizer Properties: IdentitySource: 'method.request.header.Authorization' Name: ApiCognitoAuthorizer ProviderARNs: - 'arn:aws:cognito-idp:{region}:{userpoolIdentifier}' RestApiId: !Ref ServerlessRestApi Type: COGNITO_USER_POOLS 

To attach it to a resource method, the following works (in the Swagger file):

  securityDefinitions: ApiCognitoAuthorizer: type: apiKey name: Authorization in: header x-amazon-apigateway-authtype: cognito_user_pools x-amazon-apigateway-authorizer: type: cognito_user_pools providerARNs: - arn:aws:cognito-idp:{region}:{userpoolIdentifier} 

Then add to the specific methods (in the Swagger file):

  security: - ApiCognitoAuthorizer: [] 
0
source share

Starting with AWS SAM v1.8.0, you can do this using the following syntax. You can refer to this article for more information.

In short, define a Cognito Authorizer for your API using the API Authorizer Object . Then set Auth of your lambda function to a link to this API.

 MyApi: Type: AWS::Serverless::Api Properties: StageName: Prod Auth: DefaultAuthorizer: MyCognitoAuth # OPTIONAL Authorizers: MyCognitoAuth: # Can also accept an array UserPoolArn: !GetAtt MyCognitoUserPool.Arn Identity: # OPTIONAL # OPTIONAL; Default: 'Authorization' Header: MyAuthorizationHeader # OPTIONAL ValidationExpression: myAuthValidationExp MyFunction: Type: AWS::Serverless::Function Properties: FunctionName: MyFunction ... Events: Post: Type: Api Properties: Path: /compute Method: POST RestApiId: !Ref MyApi Auth: Authorizer: MyCognitoAuth 
0
source share

All Articles