1
votes

I have multiple Cognito user pools which I use to separate users for different applications. I also have a set of APIs which are defined in API Gateway. These APIs are common and multiple applications can use them. I am trying to control which applications have access to which APIs using a Cognito resource server and custom scopes.

This is the guide I've been following: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-enable-cognito-user-pool.html

The problem I'm having is that I have to specify a user pool when creating an API Gateway authorizer. I can create multiple authorizers but I only seem to be able to select one when attaching an authorizer to an API Gateway method.

This set up means than only one user pool can ever have access to an API in API Gateway when using the Cognito authorizer. Is this correct or have I missed something?

My only option seems to be using a Lambda authorizer and doing all this manually. However, this means that I have to store a mapping between API endpoints/methods and custom scopes. If I were to take this approach, how would I verify that an access token has access to the endpoint in the incoming request?

2

2 Answers

0
votes

I've done something similar but not exactly what you are doing, but maybe it'll lead you in the right direction.

So I think you're right in that you'll need to do a Lambda authorizer, but then assume the role of the cognito user. Then if that user doesn't have access to do something IAM will blow it up.

client = boto3.client('sts')
role=event['requestContext']['authorizer']['claims']['cognito:preferred_role']

assumed_role_object = client.assume_role(
    RoleArn=role,
    RoleSessionName='APIrole'
)
credentials=assumed_role_object['Credentials']
dynamo_resource=boto3.resource(
    'dynamodb',
    aws_access_key_id=credentials['AccessKeyId'],
    aws_secret_access_key=credentials['SecretAccessKey'],
    aws_session_token=credentials['SessionToken'],
)
0
votes

There is a solution posted here: How to use multiple Cognito user pools for a single endpoint with AWS API Gateway?

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