JAVA-AWS Cognito-检查Cognito用户池中是否存在用户

JAVA-AWS Cognito-检查Cognito用户池中是否存在用户,java,authentication,aws-lambda,amazon-cognito,aws-userpools,Java,Authentication,Aws Lambda,Amazon Cognito,Aws Userpools,我想允许用户在字段中输入用户名/密码。继续之后,我想运行一个检查,看看该用户是否已经存在于用户池中。如果他们这样做,请登录并继续使用应用程序,如果他们不这样做,请转到帐户创建流程,在那里他们将被指示添加姓名、电话号码、电子邮件等 我找不到关于如何使用AWS Cognito登录用户的文档。我应该能够在一个调用中传递用户名/密码,并得到一个回复,说用户存在/用户不存在或诸如此类!我是不是遗漏了什么 任何帮助都将不胜感激。我已经浏览了文档…以列出可以使用AWS Java SDK的用户: public

我想允许用户在字段中输入用户名/密码。继续之后,我想运行一个检查,看看该用户是否已经存在于用户池中。如果他们这样做,请登录并继续使用应用程序,如果他们不这样做,请转到帐户创建流程,在那里他们将被指示添加姓名、电话号码、电子邮件等

我找不到关于如何使用AWS Cognito登录用户的文档。我应该能够在一个调用中传递用户名/密码,并得到一个回复,说用户存在/用户不存在或诸如此类!我是不是遗漏了什么


任何帮助都将不胜感激。我已经浏览了文档…

以列出可以使用AWS Java SDK的用户:

public static void list() {
    AwsBasicCredentials awsCreds = AwsBasicCredentials.create(AWS_KEY,
            AWS_SECRET);

    CognitoIdentityProviderClient identityProviderClient =
            CognitoIdentityProviderClient.builder()
                    .credentialsProvider(StaticCredentialsProvider.create(awsCreds))
                    .region(Region.of(REGION))
                    .build();

    final ListUsersRequest listUsersRequest = ListUsersRequest.builder()
            .userPoolId(POOL_ID)
            .build();

    ListUsersResponse result = identityProviderClient.listUsers(listUsersRequest);

    System.out.println("Has users:"+result.hasUsers());
    result.users().stream().map(u->u.username()).forEach(System.out::println);
}
它需要下一个依赖项(请使用最新版本):


software.amazon.awssdk

是一个如何从Java登录用户的代码示例。

我不必每次都对您的Cognito用户池进行完整扫描,而是使用Cognito的功能触发事件。对于您的用例,Cognito可以运行Lambda。你对扳机感兴趣。基本上,当用户试图通过Cognito登录到您的系统,并且用户在池中不存在时,就会触发一个触发器,让您登录用户并将其迁移到Cognito

传入的数据如下所示:

{
    "version": "1",
    "triggerSource": "UserMigration_Authentication",
    "region": "us-west-2",
    "userPoolId": "us-west-2_abcdef",
    "userName": "theusername@example.com",
    "callerContext": {
        "awsSdkVersion": "aws-sdk-unknown-unknown",
        "clientId": "yourclientid"
    },
    "request": {
        "password": "theuserpassword",
        "validationData": null,
        "userAttributes": null
    },
    "response": {
        "userAttributes": null,
        "forceAliasCreation": null,
        "finalUserStatus": null,
        "messageAction": null,
        "desiredDeliveryMediums": null
    }
}
您的Lambda将使用此密码,并最终获取用户名和密码,并确定其是否有效。如果是,您将在
response.userAttributes
字段中传回信息,以及发送Cognito欢迎电子邮件(
messageAction
)和其他一些值。例如,您可以发回:

{
    "version": "1",
    "triggerSource": "UserMigration_Authentication",
    "region": "us-west-2",
    "userPoolId": "us-west-2_abcdef",
    "userName": "theusername@example.com",
    "callerContext": {
        "awsSdkVersion": "aws-sdk-unknown-unknown",
        "clientId": "yourclientid"
    },
    "request": {
        "password": "theuserpassword",
        "validationData": null,
        "userAttributes": null
    },
    "response": {
        "userAttributes": { "email":"theusername@example.com",
                            "email_verified": "true" }
        "forceAliasCreation": null,
        "finalUserStatus": "CONFIRMED",
        "messageAction": "SUPPRESS",
        "desiredDeliveryMediums": null
    }
}
您的Lambda在Java中的外观如下:

public class MigrateUserLambda implements RequestStreamHandler {

    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        LambdaLogger logger = context.getLogger();

        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(inputStream);

        logger.log("input is " + objectMapper.writeValueAsString(rootNode));

        String email = rootNode.path("email").asText();
        String password = rootNode.path("request").path("password").asText();

        // verify user name and password in MySQL.  If ok...

        String triggerSource = rootNode.path("triggerSource").asText();

        if( triggerSource.equals("UserMigration_Authentication")) {
            JsonNode responseNode = rootNode.path("response");
            if (responseNode != null) {
                ((ObjectNode) responseNode).with("userAttributes").put("username", "theusername@example.com" );
                ((ObjectNode) responseNode).with("userAttributes").put("email_verified", "true" );
                ((ObjectNode) responseNode).put("messageAction", "SUPPRESS");
                ((ObjectNode) responseNode).put("finalUserStatus", "CONFIRMED");
            }
        }

        String output = objectMapper.writeValueAsString(rootNode);

        OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
        writer.write(output);
        logger.log("sending back " + output);

        writer.close();
    }
}

要检查用户是否存在,只需用户名

因此,对于您的场景,在用户输入用户名和密码后触发下面的
myMethod()
。那将

  • 检查用户名是否已在用户列表中
  • 如果用户名存在,请执行登录
  • 如果用户名不存在,请创建帐户


  • 您是否使用社交登录(如Facebook、谷歌等)?您使用的SDK版本是什么?你有多少用户?传递用户名/密码以确定帐户是否存在是一个巨大的安全漏洞,因为它允许任何人找出有效的用户名。不允许社交登录。我们有一个应用程序,其中用户通过提供用户名和密码登录,现在正通过mySQL数据库进行身份验证。但是现在我们想要将用户从mySQL数据库移动到Cognito用户池。但是,每个用户都会有一封关联的电子邮件链接到他们的帐户。到目前为止,我们有大约2万用户。所以,为了不让每个用户都重置密码,我想一次一个地迁移用例,用户将尝试登录到我们的应用程序,然后我们尝试从用户池对用户进行身份验证。如果用户池中没有这样的用户,那么它将针对mySQl进行身份验证,如果成功,那么它将该用户迁移到用户池此解决方案将不起作用-
    ListUsersRequest
    一次只能返回60个用户。如果您的cognito有成百上千的用户,那么您首先必须执行for循环(可能是成百上千次)首先获取所有用户@ᴛʜᴇᴘᴀᴛᴇʟ你说得对,我没有考虑用户数量,因此建议了一个糟糕的解决方案。
    public class MigrateUserLambda implements RequestStreamHandler {
    
        public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
            LambdaLogger logger = context.getLogger();
    
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode rootNode = objectMapper.readTree(inputStream);
    
            logger.log("input is " + objectMapper.writeValueAsString(rootNode));
    
            String email = rootNode.path("email").asText();
            String password = rootNode.path("request").path("password").asText();
    
            // verify user name and password in MySQL.  If ok...
    
            String triggerSource = rootNode.path("triggerSource").asText();
    
            if( triggerSource.equals("UserMigration_Authentication")) {
                JsonNode responseNode = rootNode.path("response");
                if (responseNode != null) {
                    ((ObjectNode) responseNode).with("userAttributes").put("username", "theusername@example.com" );
                    ((ObjectNode) responseNode).with("userAttributes").put("email_verified", "true" );
                    ((ObjectNode) responseNode).put("messageAction", "SUPPRESS");
                    ((ObjectNode) responseNode).put("finalUserStatus", "CONFIRMED");
                }
            }
    
            String output = objectMapper.writeValueAsString(rootNode);
    
            OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
            writer.write(output);
            logger.log("sending back " + output);
    
            writer.close();
        }
    }
    
    /**
    * let's say you call this method when user enters username and password
    * @param context context
    * @param identityProvider cognito client
    * @param username user entered username
    * @param password user entered password
    * @return
    */
    private void myMethod(Context context, AWSCognitoIdentityProvider identityProvider, String username, String password) {
        
        boolean userExists = userExists(context, identityProvider, username);
        
        if(userExists) {
            // perform sign in with provided password
        } else {
            // create account
        }
    }
    
    
    /**
    * @param context context
    * @param identityProvider cognito client
    * @param username user entered username
    * @return true if username is already in use, false otherwise
    */
    private boolean userExists(Context context, AWSCognitoIdentityProvider identityProvider, String username) {
        LambdaLogger logger = context.getLogger();
    
        try {
            AdminGetUserRequest getUserRequest = new AdminGetUserRequest();
            getUserRequest.setUserPoolId("cognitoPoolId");
            getUserRequest.setUsername(username);
    
            AdminGetUserResult getUserResult = identityProvider.adminGetUser(getUserRequest);
    
            return true;
        } catch (UserNotFoundException userNotFoundException) {
            logger.log("UserNotFoundException! " + userNotFoundException.toString());
            return false;
        } catch (Exception e) {
            return false;
        }
    }