Search code examples
amazon-web-servicesaws-lambdaaws-api-gatewayamazon-cognitoaws-sam

Aws sam cognito api gateway - access token forbidden but works if it's from postman


I have a CognitoUserPool and a lambda function that requires an authenticated user.

When making a request with the token acquired from postman that opens the aws UI login, it works, but when using the token from a curl login it doesn't got 403 forbidden, any idea of what I'm missing?

My template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  Env:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - test
      - prod

Description: >-
  sam-app
Transform:
- AWS::Serverless-2016-10-31

Globals:
  Function:
    Timeout: 100
    Runtime: nodejs16.x
    MemorySize: 128

Resources:
  CognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: !Sub ${Env}-Cognito-User-Pool
      Policies:
        PasswordPolicy: 
          MinimumLength: 8
      UsernameAttributes:
        - email
      AutoVerifiedAttributes:
        - email
      Schema:
        - AttributeDataType: String
          Name: email
          Required: false

  CognitoUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      UserPoolId: !Ref CognitoUserPool
      ClientName: !Sub ${Env}-CognitoUserPoolClient
      GenerateSecret: false
      CallbackURLs:
        - http://localhost:3000
      LogoutURLs:
        - http://localhost:3000
      AllowedOAuthFlowsUserPoolClient: true
      ExplicitAuthFlows:
        - ALLOW_ADMIN_USER_PASSWORD_AUTH
        - ALLOW_USER_PASSWORD_AUTH
        - ALLOW_CUSTOM_AUTH
        - ALLOW_USER_SRP_AUTH
        - ALLOW_REFRESH_TOKEN_AUTH
        - ALLOW_USER_PASSWORD_AUTH
      AllowedOAuthFlows:
        - code
        - implicit
      SupportedIdentityProviders:
        - COGNITO
      AllowedOAuthScopes:
        - openid
        - email
        - profile

  CognitoDomainName:
    Type: AWS::Cognito::UserPoolDomain
    Properties:
      Domain: !Sub ${Env}-domain-test
      UserPoolId: !Ref CognitoUserPool

  HttpApi:
    Type: AWS::Serverless::HttpApi
    DependsOn: CognitoUserPoolClient
    Properties:
      StageName: !Ref Env
      Auth:
        Authorizers:
          CustomCognitoAuthorizer:
            UserPoolArn: !GetAtt CognitoUserPool.Arn
            AuthorizationScopes:
              - email
            IdentitySource: "$request.header.Authorization"
            JwtConfiguration:
              issuer: !Sub https://cognito-idp.${AWS::Region}.amazonaws.com/${CognitoUserPool}
              audience:
                - !Ref CognitoUserPoolClient
      CorsConfiguration:
        AllowMethods:
          - GET
        AllowHeaders: '*'
        AllowOrigins:
          - '*'

  getAllItemsFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/handlers/get-all-items.getAllItemsHandler
      Events:
        DosGet:
          Type: HttpApi
          Properties:
            Auth:
              Authorizer: CustomCognitoAuthorizer
            Path: /
            ApiId: !Ref HttpApi
            Method: GET

The curl that I use to login, got it from this post AWS - Cognito Authentication - Curl Call - Generate Token Without CLI - No Client Secret

Method: POST
Endpoint: https://cognito-idp.{REGION}.amazonaws.com/
Content-Type: application/x-amz-json-1.1
X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth
Body:
{
    "AuthParameters" : {
        "USERNAME" : "YOUR_USERNAME",
        "PASSWORD" : "YOUR_PASSWORD"
    },
    "AuthFlow" : "USER_PASSWORD_AUTH", // Don't have to change this if you are using password auth
    "ClientId" : "APP_CLIENT_ID"
}

Solution

  • After a bit of digging, I solved the issue, by analyzing the token that was generated from each method I saw a difference.

    The token acquired from the aws UI.

    {
     "scope": "aws.cognito.signin.user.admin"
    }
    

    And the one from curl login

    {
     "scope": "openid profile email"
    }
    

    So the solution was to add aws.cognito.signin.user.admin as part of my UserPoolClient AllowedOAuthScopes

    AllowedOAuthScopes:
     - openid
     - email
     - profile
     - aws.cognito.signin.user.admin
    

    and on my HttpApi AuthorizationScopes

    AllowedOAuthScopes:
     - email
     - aws.cognito.signin.user.admin