How to use multiple Cognito user pools for a single endpoint with AWS API Gateway?
Asked Answered
T

6

10

I've recently implemented an API Gateway as a proxy with a single proxy endpoint.

I'm using Cognito as authorisation mechanism and as long as I have only one user pool everything is fine.

What I am trying to achieve is to be able to allow users from different user pools, but in the AWS Console I just seem to be able to select one Cognito mechanism which is only one user pool.

Is there a way to allow multiple user pool through another mean ? Is there an alternative best practice for this scenario ? I really need users to be in separate user pools so their authentication attributes are not shared and their accounts not mutualised.

Thank you

Threemaster answered 18/10, 2019 at 15:27 Comment(0)
T
6

As of today, the only viable solution to this problem seems to use a Lambda function to authorize users, retrieving their user pool ID in the token information and then comparing to it to a list of allowed user pools in order to give them access or not.

Threemaster answered 24/1, 2020 at 10:56 Comment(3)
if can share sample of Lambda code, it would be of great help, like what is the response format and etc. Thank you for your reply, it was of great help.Prayer
Hey @Prayer did you find a solution for your issue?Gahnite
In aws lambda authorizer blueprint, there is some template kind of python code in was available I used it and modified to my need.Prayer
U
11

The console doesn't allow creating multiple cognito pool users but the CLI does, I'm not sure if all programmatic updates (like terraform or cloudformation) can do it, but CLI worked for me. Try this: https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-authorizer.html

Your CLI command might look something similar to this:

    aws apigateway create-authorizer 
    --rest-api-id xxxxxxx 
    --name 'cognito-auth-name' 
    --type COGNITO_USER_POOLS 
    --provider-arns arn:aws:cognito-idp:arn-of-userpool arn:aws:cognito-idp:arn-of-userpool arn:aws:cognito-idp:arn-of-userpool
    --identity-source 'method.request.header.Authorization'
Uhf answered 26/7, 2020 at 9:32 Comment(1)
Hi, Tried this method, but it's throwing conflict exception, concurrent modification exception. Any idea. Pls helpChichihaerh
T
6

As of today, the only viable solution to this problem seems to use a Lambda function to authorize users, retrieving their user pool ID in the token information and then comparing to it to a list of allowed user pools in order to give them access or not.

Threemaster answered 24/1, 2020 at 10:56 Comment(3)
if can share sample of Lambda code, it would be of great help, like what is the response format and etc. Thank you for your reply, it was of great help.Prayer
Hey @Prayer did you find a solution for your issue?Gahnite
In aws lambda authorizer blueprint, there is some template kind of python code in was available I used it and modified to my need.Prayer
A
6

I found Abhay Nayak answer useful, it helped me to achieve my scenario:

  • Allowing authorization for a single endpoint, using JWTs provided by different Cognitos, from different aws accounts. Using cognito user pool authorizer, not custom lambda authorizer.

Here is the authorizer and endpoint from my serverless .yml template:

functions:
  service:
    handler: service.service
    events:
      - http:
          path: service
          method: get
          authorizer:
            type: COGNITO_USER_POOLS
            authorizerId:
              Ref: ApiGatewayAuthorizer


resources:
  Resources:
    ApiGatewayAuthorizer:
      Type: AWS::ApiGateway::Authorizer
      Properties:
        AuthorizerResultTtlInSeconds: 300
        Name: API_AUTH_cognito_authorizer
        IdentitySource: method.request.header.Authorization
        RestApiId:
          Ref: ApiGatewayRestApi
        Type: COGNITO_USER_POOLS
        ProviderARNs:
          - arn:aws:cognito-idp:us-east-1:account1:userpool/userpool1
          - arn:aws:cognito-idp:us-east-1:account1:userpool/userpool2
          - arn:aws:cognito-idp:us-east-1:account2:userpool/userpool3
          - arn:aws:cognito-idp:us-east-1:account2:userpool/userpool4
Amphictyon answered 15/2, 2021 at 22:46 Comment(0)
B
1

There are multiple ways of "Controlling and Managing Access to a REST API in API Gateway" and User Pool as Authorizer is one of them. In your case, I would go with IAM Permissions by attaching a policy to an IAM user representing the API caller, to an IAM group containing the user, or to an IAM role assumed by the user.

As a reference, I'm suggesting IAM Permissions instead of Lambda authorizers as I don't see a need to "control access to REST API methods using bearer token authentication as well as information described by headers, paths, query strings, stage variables, or context variables request parameters" in your request.

Blackandwhite answered 23/1, 2020 at 19:12 Comment(1)
Thanks for your answer. Hower I need a pool of users since I have to retrieve information about each user (getting those info directly from the token). I don't want o have an IAM user for each end user since it's not made to store OAuth attributes for example. Moreover, with your proposal, I won't be able to register users through the use of OAuth federated Identities either, so it's not a solution.Threemaster
R
0

Using python boto3,

import boto3
api_client=boto3.client('apigateway', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, region_name=region_name)
api_client.update_authorizer( restApiId='restAPIID', authorizerId='AuthosizerID', patchOperations=[ { 'op': 'add', 'path': '/providerARNs', 'value': 'COGNITO_USER_POOL_ARN' } ])

enter image description here

Ramrod answered 10/5, 2022 at 11:53 Comment(0)
E
0

Using AWS CDK,

const userPool = new cognito.UserPool(this, 'UserPool');

const auth = new apigateway.CognitoUserPoolsAuthorizer(
  this, 
  'booksAuthorizer',
  { cognitoUserPools: [userPool] }
);

declare const books: apigateway.Resource;
books.addMethod(
  'GET',
  new apigateway.HttpIntegration('http://amazon.com'),
  {
    authorizer: auth,
    authorizationType: apigateway.AuthorizationType.COGNITO,
  }
);

Source: https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway-readme.html#cognito-user-pools-authorizer

Epistle answered 17/1, 2023 at 14:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.