This Git monorepository contains a sample Java REST API application configured to use Keycloak for access management.
The project was bootstrapped using Spring Initializer with the following dependencies:
- Spring Boot Web (spring-boot-starter-web) for building RESTful APIs.
- JUnit Jupiter, Hamcrest, and Mockito (spring-boot-starter-test) for unit testing.
- Spring Security OAuth2 Resource Server (spring-boot-starter-oauth2-resource-server) to enable OIDC integration with Keycloak.
- Jacoco for generating test coverage reports.
- Spring Data and Hibernate Validator for data access and validation.
- Redis is used as 2nd level cache (Using Redisson driver).
- Spring Doc Open API for API documentation.
- Liquibase with PostgreSQL as the database for managing database migrations.
- TestContainers to run tests in an isolated PostgreSQL database environment.
- Data Faker for generating test data.
- Lombok to reduce verbosity in the code.
- Jenkins for deploying to a self-hosted Kubernetes server.
- Java JDK version 21 or higher.
- Docker version 27 or higher.
This example relies on Keycloak for authentication, PostgreSQL as the database as Redis for cache. To start these dependencies, run the following commands:
./task.sh services:upAfter cloning the repository, navigate to the root directory of the project and run the following command:
./mvnw clean installTo run the customer service, use the following command in another terminal:
./mvnw -pl customer-svc spring-boot:runYou can test the API using the Swagger UI at the following URL:
http://localhost:8081/swagger-ui/index.html
- Click the Authorize button and enter
secure-apiin the client_id field. - Click the Authorize button of the popup, which will redirect you to the Keycloak authentication page.
When the Keycloak service runs for the first time, it imports a realm called App, created exclusively for testing purposes.
This realm contains two users for authentication:
- The user with the administrator role (ROLE_ADMIN) has the username
adminand passwordpassword. - The user with the analyst role (ROLE_ANALYST) has the username
analystand passwordpassword.
Note: The ROLE_ADMIN user is permitted to modify customers, while the ROLE_ANALYST user can only list them.
Once you have authenticated, you can begin testing the API endpoints using the Try it out button for each endpoint.
If you would like to view the JWT token generated by Keycloak, use the following URL, which redirects the authentication flow to jwt.io:
Since Keycloak 25, the Organization feature is available to support multi-tenancy as can be seen here.
When using the Customer API endpoints, the User and Organization of the Keycloak authenticated token are going to be synced in the Customers database.
The admin console is accessible at http://localhost:9080/admin/master/console/#/. For testing purposes, the super admin user credentials are as follows:
- Username: admin
- Password: admin
The is available at localhost:5432. For testing purposes, the superuser credentials are:
- Username: postgresql
- Password: postgresql
The modules of this repository is based on the structure of a Multi Module Project for Spring Boot:
The auth-lib directory is a library designed to share the code need to handle authenticated resources, like authenticated user and organization for Multi-tenancy.
The customer-svc module is the main app of this repository, bootstrapped with the dependencies mentioned earlier.
The docker directory is not a Maven module.
- The
jenkinsdirectory contains a Dockerfile that is used to build the Docker Agent image, which will be utilized in the Pipeline. - The
postgresqldirectory contains a Dockerfile to build the image for PostgreSQL used in this example. For development convenience, when the container runs for the first time, it will create two databases by default: one for Keycloak and one for PostgreSQL. - The
keycloakdirectory contains a Docker Compose template to run Keycloak. For convenience, when it runs for the first time, it will import a development realm and enable the organization feature.
See here for more details on how to build the Docker image using Jenkins, push the built image to the Docker Image Registry, and deploy it to Kubernetes.