Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Cognito user pools groups data in Lambda function

I am using Cognito user pool for authentication in AWS. When an authorized user hits an API, I want to get the Cognito user pool group in which user present. I have tried many ways like

{
    "role" : "$context.identity.role",
}

and

{
    "arn": $context.identity.userArn
}

(Above are just examples I have tried)

But, I am getting data as an empty string. Please help me solve this.

Thank you...

like image 488
Sai Avatar asked Jun 13 '18 05:06

Sai


People also ask

How do you get a Cognito user in Lambda?

Create a Cognito user. Confirm the user so they can sign in. Log the user in to get a JWT token. Use the token to invoke our API endpoint which will call the function and return the cognito identity id.

What is the interaction between Lambda Cognito and API gateway?

API Gateway validates the tokens from a successful user pool authentication, and uses them to grant your users access to resources including Lambda functions, or your own API. You can use groups in a user pool to control permissions with API Gateway by mapping group membership to IAM roles.

How do you add a Cognito user to Dynamodb using Lambda?

Create an IAM Role for your Lambda Function Access your IAM Management console and select Roles from the left menu. Click Create role and select the AWS Service Lambda role. Once both are highlighted, click Next: Permissions. Name your role whatever you want, as long as it's recognizable to you, and click Create role.


2 Answers

This can be achieved using the Cognito Identity Service Provider from the AWS SDK.

You can retrieve the user sub (subject) from event.requestContext.identity.cognitoAuthenticationProvider as follows:

let userSub = event.requestContext.identity.cognitoAuthenticationProvider.split('CognitoSignIn:')[1]
let UserPoolId = event.requestContext.identity.cognitoAuthenticationProvider.split(',')[0].split('/')[1]

You would use this along with the user pool id which can also be extracted from the above value in the listUsers function of the Cognito Identity Service Provider to retrieve the users Username:

let userParams = {
    UserPoolId,
    Filter: 'sub=\"' + userSub + '\"',
    Limit: 1
  }

  try {
    const users = await cognitoISP.listUsers(userParams).promise()
    Username = users.Users[0].Username
  } catch (e) {
    // Handle your error
  }

see: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#listUsers-property

This Username along with the User Pool Id would then be used with the adminListGroupsForUser function from the Cognito Identity Service Provider to retrieve an array of the groups the user belongs to:

 try {
    let data = await cognitoISP.adminListGroupsForUser({
      UserPoolId,
      Username
    }).promise()
    groups = data.Groups
  } catch (e) {
    // Handle your error
  }

see: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#adminListGroupsForUser-property

Your lambda functions would need to have access to the following on your cognito user pool:

- cognito-idp:ListUsers
- cognito-idp:AdminListGroupsForUser

see: https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/index.html

like image 157
William Alagaratnam Avatar answered Oct 20 '22 04:10

William Alagaratnam


If you are adding the context in the authorizer, that context will be accessible in the lambda by event.requestContext.authorizer

note this is by adding the context on the authorizer response

{
  Version: "",
  Statement: ...,
  Context: {
     myProperty: "something"
  }
}

https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html

EDIT: Just noticed that you might be using cognito authorizer instead of the custom authorizer, which in that case this might help you

https://forums.aws.amazon.com/thread.jspa?threadID=238437

you suppose to get the user information through

$context.authorizer.claims.sub
like image 1
dege Avatar answered Oct 20 '22 02:10

dege