Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lambda is not authorized to perform: cognito-idp:ListUsers #1565

Closed
engharb opened this issue Sep 4, 2018 · 7 comments
Closed

lambda is not authorized to perform: cognito-idp:ListUsers #1565

engharb opened this issue Sep 4, 2018 · 7 comments
Labels
Cognito Related to cognito issues

Comments

@engharb
Copy link

engharb commented Sep 4, 2018

What is the current behavior?
I want to create a lambda function trigger PreSignUp and checks if there are other users already signed up using the same email.

here is my function:

'use strict';

const AWS = require('aws-sdk');
const cognitoIdp = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'});

exports.handler = function(event, context) {
  console.log(JSON.stringify(event));

  // check if email is already in use
  if (event.request.userAttributes.hasOwnProperty('email')) {
    const email = event.request.userAttributes.email;
    
    const params = {
      UserPoolId: event.userPoolId,
      Filter: 'email = "' + email + '"',
    };
    
    cognitoIdp.listUsers(params).promise()
    .then (results => {
      console.log(JSON.stringify(results));
      // if the usernames are the same, dont raise and error here so that
      // cognito will raise the duplicate username error
      if (results.Users.length > 0 && results.Users[0].Username !== event.userName) {
        console.log('Duplicate email address in signup. ' + email);
        context.done(Error('A user with the same email address exists'));
      }
      context.done(null, event);
    })
    .catch (error => {
      console.error(error);
      context.done(error);      
    });
  }
};

I used to get such error

lambda is not authorized to perform: cognito-idp:ListUsers

Do you have any suggestion and how to configure the IAM-lambda role.
My current lambda role:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
@engharb
Copy link
Author

engharb commented Sep 5, 2018

Here is my solution:

data "aws_iam_policy_document" "pre_signup_policy_doc" {
  statement {
    sid    = ""
    effect = "Allow"

    actions = ["cognito-idp:ListUsers"]

    resources = ["*"]
  }
}

resource "aws_iam_role_policy" "iam_for_presignup_lambda_policy" {
  role = "${aws_iam_role.iam_for_presignup_lambda.id}"
  policy = "${data.aws_iam_policy_document.pre_signup_policy_doc.json}"
  //  policy = <<EOF
  //{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "cognito-idp:ListUsers" ], "Resource": "*" } ] }
  //EOF
}

@engharb engharb closed this as completed Sep 5, 2018
@mrcoles
Copy link
Contributor

mrcoles commented Dec 17, 2018

@engharb can you share some context of how you’d use that data and resource snippet? I see there’s a <functionname>-cloufromation-template.json in my amplify project and maybe I can edit that?

(Also, does that duplicate check work for you, i.e., are you using the hosted UI and does it do something useful when you return that error?)

@engharb
Copy link
Author

engharb commented Dec 18, 2018

@mrcoles based on my knowledge this is separated issue. I mean there is no direct relation between configuring your aws-infrastructure than your-amplify-project settings. In order to be able to check i.e the existence of email or username in Cognito-User-Pool using Amplify-js or external API you have to create a policy enabling your Lambda functions to get access/permission to your Cognito-User-Pool (something like that).

And regarding <functionname>-cloufromation-template.json I have no idea what it is.

Honestly I'm not using Hosted UI directly. I used to create my own form and then validate the submitted data using Amplify-js API. And for social login I used to call

https://AUTH_DOMAIN/oauth2/authorize...

Not at all.

@mrcoles
Copy link
Contributor

mrcoles commented Dec 26, 2018

Thanks for the response. I was able to get it working in my AWS Amplify project. For anyone else who’s trying to figure it out…

List Users Permission

In an AWS Amplify project they auto-create a bunch of stuff for you and when you create a lambda function amplify add function it ends up in a directory like this:

./amplify/backend/function/<function_name>/

And there’s a Cloudformation file in that directory at <function_name>-cloudformation-template.json. Under Resources.lambdaexecutionpolicy.Properties.PolicyDocument.Statement, I was able to add this additional statement:

{
  "Effect": "Allow",
  "Action": ["cognito-idp:ListUsers"],
  "Resource": {
    "Fn::Sub": [
      "arn:aws:cognito-idp:${region}:${account}:*",
      {
        "region": {
          "Ref": "AWS::Region"
        },
        "account": {
          "Ref": "AWS::AccountId"
        },
        "lambda": {
          "Ref": "LambdaFunction"
        }
      }
    ]
  }
}

Error message in Hosted UI

Using the hosted UI and returning an error with the newer callback syntax, exports.handler = function(event, context, callback) { … }, and if I do callback(Error('a user with the same email address exists')), then I get the error message:

PreSignUp failed with error a user with the same email address exists.

screen shot 2018-12-26 at 11 22 25 am

However, with Social Signin, instead of showing the me error in the UI, it redirects me back to my app to a URL like this:

https://localhost:1234/auth/signin?error_description=PreSignUp+failed+with+error+a+user+with+the+same+email+address+exists.+&error=invalid_request

and I have to handle that in my UI I suppose.

This isn’t ideal, but it’s something workable. Also, I’m flabbergasted that there’s no option to have Cognito pools make emails case-insensitive.

@elorzafe
Copy link
Contributor

@mrcoles from today new User Pools can be created with case insensitivity for username input
More info [here] (https://aws.amazon.com/about-aws/whats-new/2020/02/amazon-cognito-user-pools-service-now-supports-case-insensitivity-for-user-aliases)

@notpresleybutelvis
Copy link

@engharb Thanks for bringing up the problem, I was going to post this question anyways.
@mrcoles Thanks for your solution, this worked for me too. I had to be careful of the arrays in Resource
This is how my PolicyDocument looks like after implementing what @mrcoles suggested. Now my Cognito lambda trigger has access to the UserPool.

"PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "cognito-idp:ListUsers"
              ],
              "Resource": [
                {
                  "Fn::Sub": [
                    "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*",
                    {
                      "region": {
                        "Ref": "AWS::Region"
                      },
                      "account": {
                        "Ref": "AWS::AccountId"
                      },
                      "lambda": {
                        "Ref": "LambdaFunction"
                      }
                    }
                  ]
                },
                {
                  "Fn::Sub": [
                    "arn:aws:cognito-idp:${region}:${account}:*",
                    {
                      "region": {
                        "Ref": "AWS::Region"
                      },
                      "account": {
                        "Ref": "AWS::AccountId"
                      },
                      "lambda": {
                        "Ref": "LambdaFunction"
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }

yoonjeong-choi-dev added a commit to yoonjeong-choi-dev/study-history that referenced this issue Nov 15, 2021
- 인증 및 S3에 대한 람다 트리거 추가
- Cognito 트리거의 경우, lambdatriggerc602322aPostConfirmation-cloudformation-template 수정 필요
  - Cognito 접근을 위해 Policy에 cogniot-idp 관련 권한 추가
  - aws-amplify/amplify-js#1565 참고
- 각 트리거 테스트를 위한 클라이언트 추가
  - React Router를 사용하여 각 테스트에 대한 컴포넌트 구현
@github-actions
Copy link

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Cognito Related to cognito issues
Projects
None yet
Development

No branches or pull requests

5 participants