Authentication using AWS Cognito

aws-cognito

Amazon Cognito is a cloud based service that offers authentication, authorization and user management for applications. Application users can sign in using traditional user name - password combo, Multi factor authentication or by using third party services like Google, Facebook etc.

AWS provides various APIs to programmatically access it. Java application development being a widely used language, they have provided a Java SDK for developers. AWS has a good API documentation for this as well. In this post, we will see how a simple user authentication can be done with Cognito in an application using Java.

Typical authentication steps involve:

  1. Configure a user pool in Cognito. A user pool is a directory of all users whom can be authenticated using Cognito.
  2. Add a user to the pool. We can either create user using the AWS Console or using AWS Java SDK API.
  3. Then we can use AWS Java SDK API for user authentication. If user login for the first time, Cognito will prompt them to change their default password. Once the password is changed, we will get the authentication token from Cognito. This token can be used to check if the user has already logged in to the system (helps to maintain user session).

We will see each step in detail here.

  • Configure User Pool in Cognito:

    Login to your AWS account and go to Cognito service. Click on Manage User Pools. In the next screen click on 'create a user pool' option

    aws-cognito

  • Enter the user pool name in the below screen. Here we have options for configuring the User pool. Either we can go with the defaults that AWS provides or can customize the settings. Here we choose defaults.

    aws-cognito

  • We will get summary changes as below. Then click on 'Create pool' will create the user pool.

    aws-cognito

  • We need to define an app client for accessing the user pool, which can be done by selecting the App client’s option as shown below. This app client id is needed for connecting to Cognito.

    aws-cognito

2. Add user to pool

Once the user pool is created, we need to add a user to this pool. We will add this from AWS console itself. For that go to pool details and click on Users and groups. It will prompt a screen as follows. Fill in the user details. Remember the credentials.

aws-cognito

3. User authentication using AWS Java SDK.

Below Java code snippets depicts the user authentication in Cognito.

First, we need to create a AWSCognitoIdentityProviderClient object, which can be used for connecting to Cognito.

AWSCognitoIdentityProvider awsCognitoIDPClient=null; try{ awsCognitoIDPClient = new AWSCognitoIdentityProviderClient(new BasicAWSCredentials("your access key", "your secret key")).withRegion(Regions.US_EAST_2); }catch(Exception e){ }

Now the below code can be used for login as the 'test_user'

Map<String,String> params =new HashMap<String,String>(); params.put("USERNAME","test_user"); params.put("PASSWORD","Temp@1234"); AdminInitiateAuthRequest initialRequest=new AdminInitiateAuthRequest() .withAuthFlow(AuthFlowType.ADMIN_NO_SRP_AUTH) .withAuthParameters(params) .withClientId("your client id") .withUserPoolId("user pool id"); AdminInitiateAuthResult initialResponse = awsCognitoIDPClient.adminInitiateAuth(initialRequest);

After first login, the user needs to change his password. So, the response to above call will indicate the user to change the password.

initialResponse.getChallengeName() will be NEW_PASSWORD_REQUIRED in this case.

For any further logins initialResponse.getChallengeName() will be blank and the result contains the authentication tokens from Cognito.

Then we need to provide a new password. The below code can be used for setting new password for this user.

Map<String,String> challengeResponses=new HashMap<String,String>(); challengeResponses.put("USERNAME","test_user"); challengeResponses.put("PASSWORD","Temp@1234"); challengeResponses.put("NEW_PASSWORD","Temp@5678"); AdminRespondToAuthChallengeRequest finalRequest=new AdminRespondToAuthChallengeRequest() .withChallengeName(ChallengeNameType.NEW_PASSWORD_REQUIRED) .withChallengeResponses(challengeResponses) .withClientId("your client id") .withUserPoolId("user pool id") .withSession(initialResponse.getSession()); AdminRespondToAuthChallengeResult challengeResponse= awsCognitoIDPClient.adminRespondToAuthChallenge(finalRequest);

challengeResponse.getChallengeName() will be null for a successful change. Cognito will handle the situations like invalid passwords, user not found etc as well.

The challengeResponse will contain the authentication tokens from Cognito, which can be send with further request to the applications. In the application we can again capture the token (may be in a filter) and check if the token is a valid one. The below code snippet depicts how to do it,

GetUserRequest userRes = new GetUserRequest(); userRes.setAccessToken(accessToken); GetUserResult getUserResult = awsCognitoIDPClient.getUser(userRes);

The getUserResult will contain the details of Cognito user. Thereby we can make sure that user indeed login to the system already.

Conclusion:

Cognito is service provided by AWS for user authentication. We can create a user pool for storing the details of users of our application. A user can be added to this pool either through AWS console or programmatically. We can use AWS Java SDK for authenticating this user. We have seen sample java code for authentication here.

The main advantage of using an identity manager like Cognito, is to offload the user security related tasks from application to a scalable service. AWS offers this service in pay per usage model, so that we only need to pay based on the usage.

  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img