When I implemented the authentication and authorization process with Spring Security 6, I didn't find any helpful and updated articles on this matter. So, I'll save you some time and show you how you can do that. In this blog post, we'll focus on implementing the registration, login processes, and the JWT Token authorization with AWS Cognito. You're welcome, let's get started!
What is AWS Cognito
Amazon Cognito is a product from Amazon Web Services (AWS) that controls user authentication and access for mobile apps. It's an identity platform for web and mobile apps.
Cognito's main features include:
User directory
Authentication server
Authorization service
User sign-up and authentication
Temporary security credentials
Session management
Forgotten password functionality
Cognito also provides a secure identity store that can scale to millions of users. This store securely stores user profile data for users who sign up directly and for federated users who sign in with external identity providers.
Each interview session has 2 questions from the same type
Here is the ERD for more understanding
I will assume that you already know how to install Spring Boot. Just make sure that you have the following dependencies in your pom.xml file
Let's break down each dependency:
spring-boot-starter-security: is part of the Spring Boot framework and provides a comprehensive set of security-related features.
Authentication: Helps in user authentication.
Authorization: Supports role-based and permission-based access control.
Common security configurations out of the box.
Integration with various authentication providers.
aws-java-sdk-cognitoidp: is part of the AWS SDK for Java and specifically focuses on Amazon Cognito Identity Pools.
Provides Java APIs for interacting with Amazon Cognito Identity Pools.
Enables your Java application to integrate with Amazon Cognito for user management and authentication.
Includes functionality for user sign-up, sign-in, and other identity-related operations.
mysql-connector-java: is the official JDBC driver for MySQL databases, allowing Java applications to connect and interact with MySQL databases. Because you will need to create a local database. Look up online on how to do it with IntelliJ.
spring-boot-starter-oauth2-resource-server: is part of Spring Boot and is designed to set up an OAuth 2.0 Resource Server.
Configures the application to act as a resource server, capable of processing and validating OAuth 2.0 access tokens.
Allows the application to secure its resources and endpoints using OAuth 2.0 authentication and authorization.
The architecture:
We'll use the Domain Driven Design principles:
controller: For handling HTTP requests and defining endpoints.
service: For implementing business logic.
repository: For data access to interact with databases like DynamoDB.
model: For defining domain entities and value objects.
requests: We could use Data Transfer Objects (DTO) that encapsulate data passed between layers. But for this project, we will use request classes, which serve as a form of DTO. Those classes define the structure of the data you expect to receive in your HTTP request.
config: For Spring configuration classes.
security: For security-related classes.
Here is what your src/main folder should look like:
Add the following to your application.properties file
Add the controller actions for your login and register routes in the UserController:
Add the registerUser and loginUser methods in the UserService interface and implement them in the UserServiceImpl class:
Implement the registration and login logic in the CognitoService:
Create the AWSCognitoIdentityProvider bean in your CognitoConfig class:
Implement the UserLoginRequest and UserRegistrationRequest classes:
Implement the User model:
Finally, add this to your SecurityConfig class:
Now start your Spring app, open Postman, and ensure your app is connected to your database. Run the POST /register request and you should get the following result:
You should also be able to see the new user in your AWS Cognito app.
Run the POST /login request and you should get the following result:
Don't forget to confirm manually the user account from the AWS Cognito. You can look up the documentation to see how you can also do it using Spring Boot.
Verifying authorization
Spring Security supports protecting endpoints by using two forms of OAuth 2.0 Bearer Tokens:
JWT
Opaque Tokens
We are going to use JWT. You can learn more about it in the Spring documentation.
Spring Boot will do it by checking the token provided by our client (in this case, Postman), verifying if it's a valid Cognito token, and either returning success or unauthorized statuses.
For more
Update your Securityconfig
Add this line to your application.properties file:
Create a simple.priv file and paste the following key. Or create your own RSA key:
That's it. Now let's say you want to create a question. Simply create the endpoint and add the controller action in the QuestionController:
@AuthenticationPrincipal is used to inject the JSON Web Token (JWT) directly into the method parameter and check if it's valid one.
I'll let you implement the logic in the service, request, repository and model. Ciao.