How to list all Amazon Cognito users from java

How to list all Amazon Cognito users from java

Amazon Cognito is a robust solution for user- and identity-pool management. For java users Amazon provides a more or less simple SDK. In this short article I want to describe how to list all users from an user pool.

The SDK doesn’t provide a listAllUsersAtOnce functionality out of the box. There is a listUsers method which is based on pagination. If there are still more users left after a successful listUsers-request, the listUsers-result contains a PaginationToken, that can be used for the next request. The maximum number of users to be returned in one single request is 60.

The listUsers workflow

ListUsersResult result = identityProvider.listUsers(listUsersRequest);
...

while (result.getPaginationToken() != null) {
	try {
		listUsersRequest.setPaginationToken(result.getPaginationToken());
		result = identityProvider.listUsers(listUsersRequest);
		...
	} catch (TooManyRequestsException e) {
		...
	}
}

Rate limits

Amazon has defined rate limits for all Cognito API request. The rate limits for Amazon Cognito are describe here [Amazon Cognito rate limits]. If the rate limit is exceeded the API fires a ```TooManyRequestsException``.

Rate limit for all list APIs: 5 per second

Complete code example

My user model

@Data @Builder
public class MyUserModel {
	private String id;
	private String firstname;
}

The Amazon Cognito connector

@Slf4j
public class AmazonCognitoConnector {

	private final static String AWS_ACCESS_KEY = "<YOUR AWS ACCESS KEY>";
	private final static String AWS_SECRET_KEY = "<YOUR AWS SECRET KEY>";
	private final static String AWS_USER_POOL_ID = "<YOUR USER POOL ID>";
	private final static String AWS_REGION = "<YOUR AWS REGION>";

	private AWSCognitoIdentityProvider identityProvider;

	public AmazonCognitoConnector() {
		BasicAWSCredentials creds = new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY);

		AWSCognitoIdentityProviderClientBuilder builder = AWSCognitoIdentityProviderClientBuilder.standard()
				.withCredentials(new AWSStaticCredentialsProvider(creds));
		builder.setRegion(AWS_REGION);

		this.identityProvider = builder.build();
	}

	public List<MyUserModel> listAllUsers(int limit) {
		/** check limit 0<limit<=60 "Maximum number of users to be returned" */
		if (limit <= 0 || limit > 60) {
			throw new IllegalArgumentException("limit must have a value less than or equal to 60");
		}

		List<MyUserModel> users = new ArrayList<>();

		/** prepare Cognito list users request */
		ListUsersRequest listUsersRequest = new ListUsersRequest();
		listUsersRequest.withUserPoolId(AWS_USER_POOL_ID);
		listUsersRequest.setLimit(limit);

		/** send list users request */
		ListUsersResult result = identityProvider.listUsers(listUsersRequest);

		List<UserType> userTypeList = result.getUsers();
		users.addAll(userTypeList.stream().map(u -> convertCognitoUser(u)).collect(Collectors.toList()));

		/**
		 * as long as there is a pagination token in the list users result => resend
		 * list users request with pagination token.
		 */
		while (result.getPaginationToken() != null) {
			try {
				listUsersRequest.setPaginationToken(result.getPaginationToken());
				result = identityProvider.listUsers(listUsersRequest);

				users.addAll(userTypeList.stream().map(u -> convertCognitoUser(u)).collect(Collectors.toList()));
			} catch (TooManyRequestsException e) {
				/** cognito hard rate limit for "list users": 5 per second. */
				try {
					log.warn("Too many requests", e);
					Thread.sleep(200);
				} catch (InterruptedException e1) {
					log.warn("Error while sleeping", e);
				}
			}
		}

		return users;
	}

	protected MyUserModel convertCognitoUser(UserType awsCognitoUser) {

		MyUserModel.MyUserModelBuilder builder = MyUserModel.builder();

		for (AttributeType userAttribute : awsCognitoUser.getAttributes()) {
			switch (userAttribute.getName()) {
			case "sub":
				builder.id(userAttribute.getValue());
				break;
			case "given_name":
				builder.firstname(userAttribute.getValue());
				break;
			}
		}

		return builder.build();
	}
}

The complete gradle project is here on github.com/elmolm


Florian Schmidt

Senior Java EE Software Engineer, Swift Enthusiast, Techie, Managing Partner Sneed IT UG, Founder Smipty