1. Introduction
In this tutorial, we will look at how we can use Spring Security‘s OAuth 2.0 support to authenticate with Amazon Cognito.
Along the way, we’ll briefly take a look at what Amazon Cognito is and what kind of OAuth 2.0 flows it supports.
In the end, we’ll have a simple one-page application. Nothing fancy.
2. What is Amazon Cognito?
Cognito is a user identity and data synchronization service that makes it easy for us to manage user data for our apps across multiple devices.
With Amazon Cognito, we can:
- create, authenticate, and authorize users for our applications
- create identities for users of our apps who use other public identity providers like Google, Facebook, or Twitter
- save our app’s user data in key-value pairs
3. Setup
3.1. Amazon Cognito Setup
As an Identity Provider, Cognito supports the authorization_code, implicit, and client_credentials grants. For our purposes, let’s set things up to use the authorization_code grant type.
First, we need a bit of Cognito setup:
- Create a User Pool
- Add a User – we’ll use this user to log into our Spring Application
- Create App Client
- Configure App Client
In the configuration of the application client, make sure the CallbackURL matches the redirectUriTemplate from the Spring config file. In our case, this will be:
http://localhost:8080/login/oauth2/code/cognito
The Allowed OAuth flow should be Authorization code grant. Then, on the same page, we need to set the Allowed OAuth scope to openid.
3.2. Spring Setup
Since we want to use OAuth 2.0 Login, we’ll need to add the appropriate Spring Security dependencies to our application:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-boot-starter-security-oauth2-client</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-jose</artifactId> </dependency>
And then, we’ll need some configuration to bind everything together:
spring: security: oauth2: client: registration: cognito: clientId: clientId clientSecret: clientSecret scope: openid redirectUriTemplate: "http://localhost:8080/login/oauth2/code/cognito" clientName: cognito-client-name provider: cognito: issuerUri: https://cognito-idp.{region}.amazonaws.com/{poolId} usernameAttribute: cognito:username
And with that, we should have Spring and Amazon Cognito set up! The rest of the tutorial is just tying up a couple of loose ends.
4. Add a Landing Page
Next, we add a simple Thymeleaf landing page so that we know when we’re logged in:
<div> <h1 class="title">OAuth 2.0 Spring Security Cognito Demo</h1> <div sec:authorize="isAuthenticated()"> <div class="box"> Hello, <strong th:text="${#authentication.name}"></strong>! </div> </div> <div sec:authorize="isAnonymous()"> <div class="box"> <a class="button login is-primary" th:href="@{/oauth2/authorization/cognito}"> Log in with Amazon Cognito</a> </div> </div> </div>
Simply put, this will display our user name when we’re logged in or a login link when we’re not. Pay close attention to what the link looks like since it picks up the cognito part from our configuration file.
And then let’s make sure we tie the application root to our welcome page:
@Configuration public class CognitoWebConfiguration implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("home"); } }
5. Run the App
This is the class that will put everything related to auth in motion:
@SpringBootApplication public class SpringCognitoApplication { public static void main(String[] args) { SpringApplication.run(SpringCognitoApplication.class, args); } }
Now we can start our application, go to http://localhost:8080, and click the login link.
6. Conclusion
In this tutorial, we looked at how we can integrate Spring Security with Amazon Cognito with just some simple configuration. And then we put everything together with just a few pieces of code.
As always, the code presented in this article is available over on Github.