How to secure Spring boot REST API endpoints with Amazon Cognito

Hello, I am a full stack developer since 2010 focused for a long moment more on backend stuffs. I embraced cloud development since 2019.
Search for a command to run...

Hello, I am a full stack developer since 2010 focused for a long moment more on backend stuffs. I embraced cloud development since 2019.
Hi Wilson, Thanks for the very informative article. I followed your blog step by step up until the point where I need to sign up/sign in to generate a token via postman.
The auth URL in your screenshot looks like: https://<clientId>.auth.<aws-region>/login but when I use my clientId and aws-region, it doesnt work.
Am I missing something?
Also is the auth URL same as domain because my domain looks like: https://<app-name>.auth.<aws-region>
Hi Hari,
Glad you read the post. The auth URL is :<< https://<clientId>.auth.<aws-region>.amazoncognito.com/login >>, don't forget ".amazoncognito.com" before /login , not << https://<clientId>.auth.<aws-region>/login >>.
Hope this will help you.
Wilson KOMLAN Hi Wilson, Just to give an update, I used the auth URL in the format you mentioned: << https://<clientId>.auth.<aws-region>.amazoncognito.com/login >>
but I still couldn't get it to work. I was able to sign in, was redirected to the callback URI with an auth code on browser but postman kept complaining invalid_client and was never able to fetch a token.
So I created a new app client with a client secret, used that to signin and get an auth code from the /login endpoint.
I then manually called the oauth2/token endpoint in a new tab via postman using this auth code and bunch of other attributes as mentioned in the below guide: https://medium.com/vedity/aws-cognito-token-generation-for-rest-api-calls-d32ce909894c and managed to generate the token. I was then able to use the token to call my spring boot API.
So instead of doing it in 1 step, I ended up doing 2 steps but I am mighty pleased that my API is secure with AWS cognito, all thanks to you.
I am now planning to try out your Spring boot API + AWS Fargate guide.
Thanks a lot mate! God bless you!
Security in internet-facing or local applications is one of the most challenging parts of the software development life cycle. This post will provide a quick step-by-step guide to implementing access management for the previous REST API using Amazon ...

In this post, we will create a REST API endpoint with GET and POST methods for the previous backend using Amazon API Gateway's HTTP API. Prerequisites All you need is just an AWS account: no worries, if you are new to AWS, AWS offers you a 12-month f...

In this article, we'll build a simple CRUD JavaScript-based backend with AWS. We'll use Lambda and DynamoDB to show how you can quickly create a secure and robust app backend. Prerequisites To follow this tutorial, you need an AWS account. Thankfully...

There are many articles on how to build a real-world Spring Boot CRUD REST API or Application with MySQL as a Relational Database. In this post, we are not only going to show how to create a Spring Boot CRUD operations API, but we will also dive deep...

Before entering the AWS Cloud world, as a Java developer, it was often difficult for me to get Java-based applications online for my clients. Fortunately, I found out later that AWS provides many proven, fully managed services for deploying Java-bas...

Hello! For Java backend developers, with Spring security there are many ways to secure Spring boot Rest APIs.
Usually, implementing Spring boot bearer token functionality for Rest API requires many lines of code, hours, and the need for user management. However, using Spring boot AWS authentication thanks to Amazon Cognito, things become very simple and very very fast. We no longer need to manage users, Amazon Cognito user pool takes care of that. Cognito also allows us to share users between many Rest APIs and front-ends (web, mobile).
Sign in into Amazon console, and then search for: Cognito.

Click on Create User Pool.
In the Configure sign-in experience step, check User name, Email, and Allow users to sign in with a preferred user name options then click on Next.
In the Configure security requirements step, leave all the default options except MFA enforcement where you should choose No MFA instead of Require MFA - Recommended, then click on Next.
Step 3 : Configure sign-up experience, leave all default options, and click on Next.
Step 4: Configure message delivery, choose Send email with Cognito for Email provider and leave all other default options then click on Next.
Step 5: Integrate your app, provide the User pool name : Demo-user-pool, App client name: Dockerdemo-app, leave other default options, and click Next.
Step 6: Review and click on Create User Pool.

In the details page of the created user pool, click on App Integration tab -> Actions -> Create Cognito Domain and provide the domain name then click Create Cognito Domain.
Again, in the App Integration tab, navigate to the App client list section and click on Dockerdemo-app to preview its details.

In the App client details, scroll down to the Pinpoint analytics section and click on Edit, the Edit Hosted UI page will open.
In the Edit Hosted UI page, provide the Allowed callback URLs : https://example.com, check Cognito user pool in the Identity providers section, check all OpenID Connect scopes options then click Save changes.
Back to the App client details, the Pinpoint analytics section should look like the image below:

Make sure to save the Cognito domain from the Domain section, and the Client ID for the created client App from the App client list section.
In this section, we will create a spring boot Rest API. For demonstration purposes, you can clone the Git hub repository here and open it in your favorite IDE.
The idea here is to implement Spring Security Rest API authentication with OAuth 2.0 JWT Bearer Tokens. Instead of implementing the JWT authentication tokens generation mechanism, we will use Amazon Cognito to manage it.
Provide the needed dependencies in the pom.xml file for Spring Security OAuth 2.0 support
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-
server</artifactId>
</dependency>
In the application.yaml file, specify the Authorization Server:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://cognito-idp.[AWS REGION].amazonaws.com/[USER_POOL_ID]
Create a security configuration file.
package com.wilkom.dockerdemo.security;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity // Enable Spring Security’s web
//security support
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) // To configure method-level security
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.authorizeRequests(expressionInterceptUrlRegistry -> expressionInterceptUrlRegistry
.anyRequest().authenticated())
.oauth2ResourceServer().jwt();
return http.build();
}
}
In the configuration class above, we have made each endpoint accessible only by OAuth 2.0 authenticated requests. That's all we have to do in our API Rest backend.
We will use Postman to test our Rest API.
1. Signup user into the Amazon Cognito
Open Postman and provide values from Amazon Cognito User provider settings:

2/ Callback URL: https://example.com (make sure to provide the exact callback URL you set in the Cognito)
3/ Auth URL: https://xxxxx.auth.us-east-1.amazoncognito.com/login (remember to append /login)
4/ Access Token URL : https://xxxxx.auth.us-east-1.amazoncognito.com/oauth2/token (remember to append /oauth2/token)
5/ Client ID : Dockerdemo-app App Client ID
Then click on Get New Access Token at the bottom, and the Sign-in screen will open, click on Sign up link at the bottom the get the signup screen as follow:

Enter the user name, valid email and password then click on Sign-up.
The verification code screen should appear, open the valid email box to get the verification code:

If the code verification is successful, a token will be generated, click on Use Token:

2. Make API call
Now, you can run the Spring boot app.
Go to Postman, enter a GET endpoint URL,
localhost:8080/api/

PS: In a real project, the Signup and Sign-in processes will be implemented in the front-end apps, please see this guide to do so.
As you can see, Amazon Cognito is an amazing AWS service that simplifies Spring boot backend Rest API user management.
Thanks for reading.