Enterprise Java

Integrate Spring Boot Application with Amazon Cognito

In this article, we will show how to use Amazon Cognito service for authentication users in a Spring Boot application using the OAuth 2.0 client library introduced in Spring Security 5.0.

What is AWS Cognito?

Amazon Cognito is service offered by AWS which provides user management services like sign up and sign in, in addition to providing support for granting credentials for accessing AWS services. It has its own identity provider in addition to integrating with identity providers like Facebook, Google, SAML, OpenId

What’s in It for Web Application Developers?

Web application developers (server side / single page applications) and even mobile application developers can off load user signup and authentication to Amazon Cognito and focus on implementing business requirements.

Cognito supports features like multi factor authentication (MFA), email and phone number verification, password strength management. It also supports authentication with other identity providers like Facebook, Google and custom SAML integration where cognito acts as an adapter to integrate with them.

So in short developers get to focus on business features and let AWS handle the user signup and authentication.

Setting up Amazon Cognito

Cognito contains two main components:

  • User pools – which is used for user and identity management, managing application client details (i.e the clients which would use cognito for authentication)
  • Identity pools – which is used for granting AWS credentials for accessing AWS services

Let us configure user pool and also create an application client which we can use to connect with cognito.

Creating user pool

Amazon Cognito

Creating app client

Amazon Cognito

Setting up app client

Amazon Cognito

Setting up domain name for user pool

Amazon Cognito

Creating test users

Amazon Cognito

These were the few steps to follow to setup your Cognito user pool and application client.

Configuring Spring Boot Application

We will make use of the OAuth client library included as part of Spring Security 5 and its integration with Spring Boot.

Update the pom.xml to Add OAuth Client Dependency

Add the following dependency to your pom.xml to be able to get grab the OAuth client library

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

Add the properties related to OAuth client

We need to define some properties related to registering the OAuth provider and setting up the OAuth provider. The following properties need to be added:

app.url=http://localhost:9999
cognito.rooturl=https://test-userpool.auth.eu-west-1.amazoncognito.com
spring.security.oauth2.client.registration.cognito.provider=cognito
spring.security.oauth2.client.registration.cognito.client-id=<client-id>
spring.security.oauth2.client.registration.cognito.client-secret=<client-secret>
spring.security.oauth2.client.registration.cognito.client-name=test-client
spring.security.oauth2.client.registration.cognito.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.cognito.scope=email,openid
spring.security.oauth2.client.registration.cognito.redirect-uri-template=${app.url}/login/oauth2/code/cognito

spring.security.oauth2.client.provider.cognito.authorizationUri=${cognito.rooturl}/oauth2/authorize
spring.security.oauth2.client.provider.cognito.tokenUri=${cognito.rooturl}/oauth2/token
spring.security.oauth2.client.provider.cognito.jwkSetUri=https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_Mi1q5QPXa/.well-known/jwks.json
spring.security.oauth2.client.provider.cognito.user-info-uri=${cognito.rooturl}/oauth2/userInfo
spring.security.oauth2.client.provider.cognito.userNameAttribute=username

The JWK URI is built based on the guidelines given here.

Creating an HTML Page to Show Authenticated User Detail

We have added an index.html to show the logged in user detail using Thymeleaf-Spring security dialects as shown below:

<div class="container">
	<div class="row">
		<div class="col">
			Authenticated successfully as [[${#authentication.name}]]<br/>
			Principal: [[${#authentication.principal}]]
			<div>
				<a th:href="@{/logout}" class="btn btn-primary">Logout</a>
			</div>
		</div>
	</div>
</div>

Testing the Integration

Just run the main class and the application will start running on http://localhost:9999/. On navigating to this URL you will redirected to Cognito for authentication and once successfully authenticated you will be taken to the application page which looks something like:

Amazon Cognito

The complete code for the app can be found here. In the subsequent posts we will look at customizing the Principal object, making use of the user info end point, roles management via Spring security and also look at how single page applications can leverage Cognito.

Published on Java Code Geeks with permission by Mohamed Sanaulla, partner at our JCG program. See the original article here: Integrate Spring Boot Application with Amazon Cognito

Opinions expressed by Java Code Geeks contributors are their own.

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

5 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Andrea Cappalunga
Andrea Cappalunga
4 years ago

hi, I’ve tried to follow the instructions, but logout is not working. Actually it seems that the logout request towards Cognito is not being made; so user actually remains logged in. Any Idea?

rick james
rick james
4 years ago

Also having issues with the logout functionality. Other than that it is working pretty good as explained.

Shashi Shekhar
Shashi Shekhar
4 years ago

I am getting error on login as follows

“Error in login: java.lang.NullPointerException null”.

And when I debugged I found that AdminInitiateAuthResult object contains following info

{
ChallengeParameters: {},
AuthenticationResult: {
AccessToken: XXX,
ExpiresIn: 3600,
TokenType: Bearer,
RefreshToken: XXX,
IdToken: XXX,
}
}

and after invoking getSession method on this authResult obj I am getting null.

vinit
vinit
3 years ago

code”:”BadRequest”,”message”:”The server did not understand the operation that was requested.”,”type”:”client

Adam Dewing
Adam Dewing
3 years ago
Reply to  vinit

I had the same issue. The problem is that you need to setup a domain name for it. You do this on AWS under User Pools -> App Integration -> Domain Name page. Then you need to setup a Amazon Cognito domain. Hope this helps someone as this took me several hours of wasted time.

Tom Davidson
Tom Davidson
3 years ago

Thanks for the great tutorial. I can get this to work on localhost, but when I update all the config for elastic beanstalk and upload the JAR, it doesn’t work. I can see the sign in page but it won’t sign me in.

Back to top button