Java Lambda通过sub查询Cognito用户遇InvalidParameterException问题
First off, let’s rule out the SDK bug possibility right away: if your AWS CLI request works fine, the Cognito API itself supports this query, so the issue is almost certainly in how you’re handling string escaping in your Java code.
The Root Cause: Java vs. CLI String Escaping Rules
The Cognito ListUsers API requires double quotes around attribute values in the filter string, and those quotes need to be escaped with a backslash (e.g., sub = \"user-sub-123\"). Here’s where Java and CLI differ:
- In the CLI, you can directly pass
--filter "sub = \"user-sub-123\""because the shell handles the escaping correctly. - In Java, a single backslash is an escape character for the string itself. So to send a literal backslash to Cognito, you need to escape the backslash with another backslash.
Fixing the Filter String
Let’s look at common mistakes and their fixes:
❌ Incorrect Java Filter String
// This sends "sub = "user-sub-123"" to Cognito (no escaped quotes) String filter = "sub = \"user-sub-123\"";
Cognito receives unescaped double quotes here, which breaks the filter parsing logic.
✅ Correct Java Filter String (Double-Escaped Quotes)
// This sends "sub = \"user-sub-123\"" to Cognito (properly escaped) String filter = "sub = \\\"user-sub-123\\\"";
The double backslash (\\) tells Java to output a literal backslash, and the following " becomes \" in the final string sent to Cognito.
✅ Alternative: Use Single Quotes (Simpler)
Cognito also accepts single quotes around attribute values, which eliminates the need for escaping double quotes entirely:
// No escaping needed, and this works just as well String filter = "sub = 'user-sub-123'";
This is often the cleaner approach to avoid escape-related headaches.
Full Working Code Example (AWS SDK for Java 2.x)
import software.amazon.awssdk.services.cognitoidentityprovider.CognitoIdentityProviderClient; import software.amazon.awssdk.services.cognitoidentityprovider.model.ListUsersRequest; import software.amazon.awssdk.services.cognitoidentityprovider.model.ListUsersResponse; public class CognitoUserLookup { public void getUserBySub(String userPoolId, String sub) { try (CognitoIdentityProviderClient cognitoClient = CognitoIdentityProviderClient.create()) { // Using single quotes to avoid escaping String filter = String.format("sub = '%s'", sub); ListUsersRequest request = ListUsersRequest.builder() .userPoolId(userPoolId) .filter(filter) .build(); ListUsersResponse response = cognitoClient.listUsers(request); response.users().forEach(user -> { System.out.println("Found user: " + user.username()); // Process user data here }); } catch (Exception e) { System.err.println("Error fetching user: " + e.getMessage()); throw e; } } }
Verify Your Filter String
To confirm you’re sending the right filter to Cognito, add a debug print statement before making the API call:
System.out.println("Sending filter: " + filter);
If using double-escaped quotes, the output should be sub = \"user-sub-123\". If using single quotes, it’ll be sub = 'user-sub-123'—both are valid for Cognito.
Since your CLI request works, this fix should resolve the InvalidParameterException and let you retrieve users by their sub attribute successfully.
内容的提问来源于stack exchange,提问作者Fabio França

