You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

AWS Cognito新手求助:USER_SRP_AUTH认证问题及Java示例需求

AWS Cognito新用户认证问题排查+Java示例代码

Hey there! 刚接触AWS Cognito碰到认证问题太正常了,我先帮你梳理下常见的报错原因,再给你一个完整的Java认证示例代码,你可以对照排查。

常见的认证失败原因

  • 用户状态异常:新创建的用户默认处于FORCE_CHANGE_PASSWORD状态,必须先修改初始密码才能完成正常认证,这是最常见的新手坑
  • 配置参数错误:检查用户池ID、客户端ID是否正确,客户端是否开启了ADMIN_USER_PASSWORD_AUTH认证流程,以及代码配置的区域是否和用户池所在区域一致
  • 权限不足:确保执行认证的IAM角色拥有cognito-idp:AdminInitiateAuthcognito-idp:AdminRespondToAuthChallenge的权限
  • SDK版本兼容:建议使用最新的AWS Java SDK v2版本,避免旧版本的兼容性问题

你提供的报错堆栈不完整,如果是NotAuthorizedException,大概率是用户状态需要改密码或者凭证错误,可以先从上面几点排查。

Java认证示例代码

首先确保你的项目引入了AWS Cognito SDK依赖(以Maven为例):

<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>cognitoidentityprovider</artifactId>
    <version>2.20.0</version> <!-- 建议使用最新稳定版 -->
</dependency>

下面是完整的认证代码,包含正常认证和新用户强制改密码的流程:

import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cognitoidentityprovider.CognitoIdentityProviderClient;
import software.amazon.awssdk.services.cognitoidentityprovider.model.*;
import java.util.Map;

public class CognitoUserAuth {
    // 替换成你自己的用户池信息
    private static final String USER_POOL_ID = "us-east-1_XXXXXXXXX";
    private static final String CLIENT_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
    private static final Region REGION = Region.US_EAST_1; // 替换成用户池所在区域

    public static void main(String[] args) {
        String username = "test-user";
        String initialPassword = "InitialPass123!";
        String newPassword = "NewPass456!";

        // 初始化Cognito客户端
        try (CognitoIdentityProviderClient cognitoClient = CognitoIdentityProviderClient.builder()
                .region(REGION)
                .build()) {

            attemptUserAuth(cognitoClient, username, initialPassword, newPassword);
        } catch (Exception e) {
            System.err.println("认证流程出错:" + e.getMessage());
        }
    }

    private static void attemptUserAuth(CognitoIdentityProviderClient cognitoClient, String username, String initialPassword, String newPassword) {
        AdminInitiateAuthRequest authRequest = AdminInitiateAuthRequest.builder()
                .userPoolId(USER_POOL_ID)
                .clientId(CLIENT_ID)
                .authFlow(AuthFlowType.ADMIN_USER_PASSWORD_AUTH)
                .authParameters(Map.of(
                        "USERNAME", username,
                        "PASSWORD", initialPassword
                ))
                .build();

        try {
            AdminInitiateAuthResponse authResponse = cognitoClient.adminInitiateAuth(authRequest);
            // 认证成功,输出令牌信息
            System.out.println("✅ 认证成功!");
            System.out.println("ID Token: " + authResponse.authenticationResult().idToken());
            System.out.println("Access Token: " + authResponse.authenticationResult().accessToken());
        } catch (NotAuthorizedException e) {
            if (e.getMessage().contains("FORCE_CHANGE_PASSWORD")) {
                System.out.println("🔔 用户需要修改初始密码,执行改密码流程...");
                handlePasswordChange(cognitoClient, username, initialPassword, newPassword, e.session());
            } else {
                System.err.println("❌ 认证失败:用户名或密码错误");
            }
        } catch (CognitoIdentityProviderException e) {
            System.err.println("❌ Cognito服务错误:" + e.awsErrorDetails().errorMessage());
        }
    }

    // 处理新用户强制改密码流程
    private static void handlePasswordChange(CognitoIdentityProviderClient cognitoClient, String username, String oldPassword, String newPassword, String session) {
        AdminRespondToAuthChallengeRequest challengeRequest = AdminRespondToAuthChallengeRequest.builder()
                .userPoolId(USER_POOL_ID)
                .clientId(CLIENT_ID)
                .challengeName(ChallengeNameType.NEW_PASSWORD_REQUIRED)
                .session(session)
                .challengeResponses(Map.of(
                        "USERNAME", username,
                        "NEW_PASSWORD", newPassword
                ))
                .build();

        try {
            AdminRespondToAuthChallengeResponse response = cognitoClient.adminRespondToAuthChallenge(challengeRequest);
            System.out.println("✅ 密码修改成功!");
            System.out.println("新的ID Token: " + response.authenticationResult().idToken());
        } catch (CognitoIdentityProviderException e) {
            System.err.println("❌ 密码修改失败:" + e.awsErrorDetails().errorMessage());
        }
    }
}

代码说明

  • 替换代码中的USER_POOL_IDCLIENT_IDREGION为你自己的资源信息
  • 如果你的客户端设置了秘钥,需要在authParameters中添加SECRET_HASH,可以通过HMAC-SHA256加密用户名和客户端ID生成
  • 代码中已经处理了新用户强制改密码的场景,这是新手最容易忽略的点

内容的提问来源于stack exchange,提问作者Rudra Garnaik

火山引擎 最新活动