27

I need to authorize my API end point using aws cognito userpool. I can do it manually, but I need to automate the authorization part with the serverless framework.

Does the Serverless framework have support for aws cognito?

If so, how do we setup an aws-userpool with serverless?

Ole
  • 41,793
  • 59
  • 191
  • 359
Niroshan Ranapathi
  • 3,007
  • 1
  • 25
  • 35

3 Answers3

42

Yes . Serverless (v1.5) support to Cognito user pool authorizer.

If you use previous version of serverless you have to update v1.5 or later.

For the user-pool authorization of api end point you have to specify pool arn.

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get
          integration: lambda
          authorizer:
            name: authorizer
            arn: arn:aws:cognito-idp:us-east-1:123456789:userpool/us-east-1_XXXXXX

More details read this article.

Niroshan Ranapathi
  • 3,007
  • 1
  • 25
  • 35
  • just a note, you don't necessary need to update to version 1.5, you could use custom authorizer https://serverless.com/framework/docs/providers/aws/events/apigateway#http-endpoints-with-custom-authorizers with this you have to build your authorizer that will use the user pool this might also help https://aws.amazon.com/pt/blogs/compute/introducing-custom-authorizers-in-amazon-api-gateway/ – dege Jan 16 '17 at 13:30
  • Thanks for your suggestions. But serverless introduce this feature in v1.5 – Niroshan Ranapathi Jan 16 '17 at 17:04
  • 1
    yes, I know :) I was suggesting just in case someone was using a old version of serverless pre v1.5 – dege Jan 16 '17 at 17:23
  • shall i change this "If you use previous version of serverless you have to update v1.5 or later" – Niroshan Ranapathi Jan 16 '17 at 18:02
  • No need, I guess it's clear that your answer is for 1.5, wanted just to complement :) – dege Jan 17 '17 at 10:44
  • 2
    @NiroshanRanapathi How do you set the authorizer to a Cognito User Pool that you are declaring in the Resources section of your serverless.yml? – Resist Design May 03 '18 at 01:54
  • How can I get the claims returned from `id_token`? Is it possible to pass `assess_token` except `id_token`? – BartusZak Jul 11 '19 at 11:23
  • @NiroshanRanapathi I guess serverless might be able to detect the type from the ARN number but it's not clear to me why how the "source" is determined. In the API Gateway Console that field is required. – Omnibyte May 20 '20 at 14:47
  • even though no error was thrown, this snippet didn't create a new Authorizer after deployment. I used the answer of @Dehli below which worked for me. – Omnibyte May 27 '20 at 07:02
  • how do we map cognito attributes in request mapping template or forward those attributes as input to lambda. – Dharmendra Singh Negi Nov 12 '20 at 03:57
  • This is how to get the authorizer claims of JWT inside the lambda function https://vadymhimself.medium.com/setting-up-a-cognito-user-pool-authorizer-for-node-js-lambda-in-serverless-framework-ebf3ba6e7be5 – Bolein95 Nov 25 '21 at 10:11
31

If you want to set the authorizer to a Cognito User Pool you have declared in your resources you must use CloudFormation to create the authorizer as well.

functions:
  functionName:
    # ...
    events:
      - http:
          # ...
          authorizer: 
             type: COGNITO_USER_POOLS
             authorizerId: 
               Ref: ApiGatewayAuthorizer

resources:
  Resources:
    ApiGatewayAuthorizer: 
      Type: AWS::ApiGateway::Authorizer
      Properties: 
        Name: CognitoUserPool
        Type: COGNITO_USER_POOLS
        IdentitySource: method.request.header.Authorization
        RestApiId: 
          Ref: ApiGatewayRestApi
        ProviderARNs: 
          - Fn::GetAtt:
              - UserPool
              - Arn

    UserPool:
      Type: AWS::Cognito::UserPool
Dehli
  • 5,950
  • 5
  • 29
  • 44
  • 1
    Thank you so much! serverless.yml is so poorly documented. – Bolein95 Nov 23 '21 at 06:32
  • 1
    By the way if anyone was wondering how to access the claims in the function's code: https://vadymhimself.medium.com/setting-up-a-cognito-user-pool-authorizer-for-node-js-lambda-in-serverless-framework-ebf3ba6e7be5 – Bolein95 Nov 25 '21 at 10:12
7

Serverless 1.35.1

In case someone stumbles across this how I did. Here is my working solution.

Wherever you create the user pool, you can go ahead and add ApiGatewayAuthorizer

# create a user pool as normal
CognitoUserPoolClient:
  Type: AWS::Cognito::UserPoolClient
  Properties:
    # Generate an app client name based on the stage
    ClientName: ${self:custom.stage}-user-pool-client
    UserPoolId:
      Ref: CognitoUserPool
   ExplicitAuthFlows:
   - ADMIN_NO_SRP_AUTH
   GenerateSecret: true

# then add an authorizer you can reference later
ApiGatewayAuthorizer:
  DependsOn:
  # this is pre-defined by serverless
  - ApiGatewayRestApi
  Type: AWS::ApiGateway::Authorizer
  Properties:
    Name: cognito_auth
    # apparently ApiGatewayRestApi is a global string
    RestApiId: { "Ref" : "ApiGatewayRestApi" }
    IdentitySource: method.request.header.Authorization
    Type: COGNITO_USER_POOLS
    ProviderARNs:
    - Fn::GetAtt: [CognitoUserPool, Arn]

Then when you define your functions

graphql:
  handler: src/app.graphqlHandler
  events:
  - http:
    path: /
    method: post
    cors: true
    integration: lambda
    # add this and just reference the authorizer
    authorizer:
      type: COGNITO_USER_POOLS
      authorizerId:
        Ref: ApiGatewayAuthorizer
sevensevens
  • 1,703
  • 16
  • 27