Search code examples
amazon-web-servicesaws-api-gatewayamazon-cognitoaws-userpools

Lookup cognito userpool uset based on cognito dentity pool identity in API Gateway


I am an AWS newb, so please go easy on me :) I have setup a proof of concept to proove out an authenticated API backed by lambda with the following components.

API Gateway -> backed by Lambda Federated Identities backed by AWS Cognito UserPool I have the authorizer setup in the API gateway to use the IAM role which is being provided by the Federated Identity pool.

I can see the identity (ap-southeast-2:<GUID>) coming through into the gateway ( using this in my integration request mapping template "$context.identity.cognitoIdentityId" ) from https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#context-variable-reference

From either the gateway or lambda how can I resolve the 'ap-southeast-2:<GUID>' back to the source identity which resides in the user pool. (E.g. Pull one of the custom attributes from it)

Other information if relevant, i'm using Amplify-AWS for the client calling into the API Gateway.

TIA.


Solution

  • As you're noticing, Cognito as an identity provider is not the same as Cognito as a user pool.

    • Federated Identities provide a way of giving someone identified access to your AWS resources. The identity_id the identity provider gives you can almost be thought of as a tracking code. CIP (Congito [Federated] Identity Provider) allows you to get an identity id by signing in through any number of providers (not just the user pool), and even by not signing in at all.

    • User Pools give you a way of managing users for your application (i.e. a set of usernames, emails, passwords, etc).

    This is the reason getting from identity_id back to the user pool user is hard (because, there's no guarantee it is a user pool user, it could well be someone from Facebook).

    From what you've said, however, the assumption that said identity_id came from a UserPool authentication is safe. This means you have two options:

    The official way will be to use identity:GetOpenIdToken to convert identity_id (you can ignore the logins part of the request) into an OpenId token. You can then use this token against the userpools:GetUser end point. There's a few pitfalls here, like ensuring you authenticate with a scope that allows you to see all the attributes you care about.

    Curiously, however, the value of cognitoAuthenticationProvider is not opaque, and can (unoffically) be decoded:

      // Cognito authentication provider looks like:
      // cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxxxxxx,cognito-idp.us-east-1.amazonaws.com/us-east-1_aaaaaaaaa:CognitoSignIn:qqqqqqqq-1111-2222-3333-rrrrrrrrrrrr
      // Where us-east-1_aaaaaaaaa is the User Pool id
      // And qqqqqqqq-1111-2222-3333-rrrrrrrrrrrr is the User Pool User Id
    

    The above example, with more details about how you can then use this with userpools:AdminGetUser can be found here: https://serverless-stack.com/chapters/mapping-cognito-identity-id-and-user-pool-id.html