3

Is it possible to find which user (within a user pool) a given cognito identity belongs to. In the AWS Console? Programmatically ?

In a Cognito Identity Pool, identities look like <region>:<guid>. When those identities come from a Cognito User Pool, then in the AWS Console, we can click on the identity and get access to some information. That information is limited to DateCreated and LinkedLogin=cognito-idp.<region>.amazonaws.com/<userpool_id> which only tells you this identity comes from Cognito User Pool and which pool, but that is far from actually useful. Can we actually tell which user within the user pool?

mipnw
  • 2,135
  • 2
  • 20
  • 46

2 Answers2

4

After speaking to AWS developer support I found that it's not possible to link a Cognito Identity back to a user in a Cognito User Pool

Hence, if you need to know which user your backend is executing code on behalf of, in a lambda perhaps, you have the following options:

  • Send user info inside the request. Even if the lambda invocation is authenticated with a Cognito Identity, and the lambda has access to the identity in the lambda's context, if you want user info you need to send it yourself. For exemple send the ID Token in the request, validate it server side, and extract user info from it.

  • Use Cognito Sync to create a dataset for your Cognito Identities. Store a bit of user info inside the dataset.

mipnw
  • 2,135
  • 2
  • 20
  • 46
  • Thanks for sharing this. This is pretty frustrating. It looks like it's making a support person's life so much harder, especially if you're using Cognito to reference folders per identity (as it seems you can't reference folders per Cognito user) in an S3 bucket. – Andrej Mohar May 14 '23 at 14:04
0

In the context of a node.js lambda, I can obtain the user pool identity via the following:

function getAuthenticatedUser(env, event) {
    let cognitoClient = 
        new AWS.CognitoIdentityServiceProvider(env.cognito.region);

    let userSub = event.requestContext.identity
        .cognitoAuthenticationProvider.split(':CognitoSignIn:')[1];

    let request = {
        UserPoolId: env.cognito.userPoolId,
        Filter: `sub = "${userSub}"`,
        Limit: 1
    };

    console.log(JSON.stringify(request, null, 2));
    return cognitoClient.listUsers(request).promise()
        .then((data) => {
            console.log('Cognito users list...');
            console.log(JSON.stringify(data,null,2));
            return data.Users[0]
        });
}

Where event is the standard Event structure passed into the lambda on execution. (See the API Gateway Proxy Request Event in the online AWS documentation on lambda event payloads).

hatboyzero
  • 1,929
  • 1
  • 21
  • 44
  • Looking at node.js' lambda documentation (https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html) it appears a lambda function has two parameters, the first is the event the second is the context. The documentation of the context datatype doesn't match your usage of "env" which puzzles me. Your function doesn't look like a node.js lambda... What's interesting is using API Gateway between your clients and your lambdas adds a requestContext to your lambda's events, and that requestContext contains the "sub". You don't get this if your clients calls your lambdas directly – mipnw May 16 '18 at 18:56
  • This is actually a function I call from the body of a lambda - env is a variable I have populated with environment variables that I had encrypted into a file, zipped up with the lambda source, and then decrypted on lambda execution using the AWS KMS (Key Management Service). I provide this method as an example of how to obtain the Cognito User Pool user from a Cognito Federated Identity. The `event` variable I pass into this method is very much the same `event` variable that is passed as an argument to the lambda entry point, though. – hatboyzero May 17 '18 at 02:54
  • ok thanks. That doesn't really solve my problem though, your answer is able to obtain the user from the user pool because you send the user info as part of the lambda's request (i.e. in the request you have the usersub). My question was if you only have a cognito identity, what can one do to figure out who it belongs to. After talking to AWS support they tell me it's not possible to link back an identity to a user. – mipnw May 17 '18 at 19:45
  • Understood - most of my use cases involve lambdas implemented in conjunction with either API Gateway or AppSync, so there's at least enough metadata in the `event` structure to perform the above operation in those cases... Sorry I couldn't be more help. – hatboyzero May 17 '18 at 21:13