skip to Main Content

We are migrating our server-side operations from separate Lambda functions and an API managed in API Gateway, to a single SAM deployment.

Users are registered anonymously in an existing Cognito Identity Pool and receive a token when they log in, which is used to sign all subsequent requests.

In AWS gateway, we set "Method Request" => "Authorization" to "AWS IAM" for each endpoint, which works as required:

Screengrab of AWS API Gateway

I am trying to replicate this setup in my SAM template, but cannot get it to work and nearly all of the documentation relates to user pools, rather than identity pools.

Based on this, it looks like all I should need to do is add DefaultAuthorizer: AWS_IAM to my SAM template, but this rejects all requests with a 403 error.

So far I have also tried:

Resources:
  ClientContentApi:
    Type: AWS::Serverless::Api
    Properties:
      Auth:
        DefaultAuthorizer: AWS_IAM
  ClientContentAuthorizer:
    Type: AWS::ApiGateway::Authorizer
    Properties:
      Type: TOKEN
      Name: DefaultAuthorizer
      RestApiId: !Ref ClientContentApi
      IdentitySource: "method.request.header.Authorization,method.request.header.X-Amz-Date,method.request.header.X-Amz-Security-Token"
      AuthorizerUri: "<The ARN of my identity pool>"

When I try to deploy this, I get the following error:

Invalid Authorizer URI: . Authorizer URI should be a valid API Gateway ARN that represents a Lambda function invocation.

This seems to suggest I need a separate Lambda function to authorise requests, but this wasn’t necessary previously and I’d like to avoid any unnecessary setup.

What am I doing wrong and how can I replicate my API gateway auth setup in my SAM template?

2

Answers


  1. Chosen as BEST ANSWER

    I eventually got this working with the following setup:

    The only extra information I added to my SAM template was:

    Auth:
      DefaultAuthorizer: AWS_IAM
      AddDefaultAuthorizerToCorsPreflight: false
      InvokeRole: NONE
    
    • AddDefaultAuthorizerToCorsPreflight: false prevents a potential CORS error. More info here.
    • InvokeRole: NONE prevents you from having to explicitly set permission to invoke every individual function in your SAM. More info here.

    It's also necessary to add permissions to invoke your API to the unauth IAM role for your identity pool. You should have an IAM role with the name Cognito_<your-identity-pool-name>Unauth_Role, e.g.

    { 
        "Version": "2012-10-17", 
        "Statement": [ 
            { 
                "Effect": "Allow", 
                "Action": [ 
                    "execute-api:Invoke" 
                ], 
                "Resource": [ 
                    "arn:aws:execute-api:<region>:<account_id>:<api_id>/*" 
                ] 
            } 
        ] 
    }
    

    More info here.


  2. The Type for your authorizer should be COGNITO_USER_POOLS, and you should populate the ProviderARNs property with your Identity Pool ARN, as shown below:

    Resources:
      ClientContentApi:
        Type: AWS::Serverless::Api
        Properties:
          Auth:
            DefaultAuthorizer: AWS_IAM
      ClientContentAuthorizer:
        Type: AWS::ApiGateway::Authorizer
        Properties:
          Type: COGNITO_USER_POOLS
          Name: DefaultAuthorizer
          RestApiId: !Ref ClientContentApi
          IdentitySource: "method.request.header.Authorization,method.request.header.X-Amz-Date,method.request.header.X-Amz-Security-Token"
          ProviderARNs:
            - "<The ARN of my identity pool>"
    

    Source: AWS::ApiGateway::Authorizer doc

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search