This Spring security tutorial will explore how to use Keycloak and Spring Security OAuth2 module to implement authentication and authorization in a spring boot application. We will walk step-by-step from configuring a security realm in Keycloak server and using this realm for authentication/authorization of a REST API developed using Spring Boot 3.
1. Prerequisites
To follow this tutorial, we should have a basic understanding of the following:
- What are authentication and authorization?
- OAuth2 basics
- Spring boot basics
- Spring Security basics
2. Install and Setup Keycloak
2.1. Installation
There are several methods to install Keycloak, including:
- Standalone distribution is the most common method of installing Keycloak, where we download the standalone server distribution from the official website, unzip it, and start the server.
- Docker can also be used to install by pulling the Keycloak image from Docker Hub and running it as a container.
In this article, we will use Docker to easily install and run Keycloak. We can download and start the Keycloak container by running the following commands in the terminal:
docker pull quay.io/keycloak/keycloak:latest
Run the following command starts the Keycloak container with the specified username and password for the Keycloak Administration Console. It also maps port 8180 of the container to port 8180 of the host machine.
docker run --name keycloak_server -p 8180:8180 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=password \
quay.io/keycloak/keycloak:latest \
start-dev \
--http-port=8180
Once the container is started, we can access the Keycloak Administration Console by opening a web browser and going to http://localhost:8180.
2.2. Setting Up a New Realm
Follow the instructions given in getting started with Keycloak for configuring the realm, users and roles. For this tutorial, we are using the following configuration:
Realm name: howtodoinjava-realm
ClientId: employee-management-api
Client Secret: <generated>
Username: test-user
Password: password
Role: USER
3. Spring Boot Configuration
In this article, we are reusing the APIs created for Vue.js application with Spring Boot. Here, Spring boot application will be modified to act as OAuth client and Keycloak will be used as authorization server.
3.2. Maven
To configure Spring Boot Security Oauth2 to use Keycloak as Identity Provider, we need to add the following Maven dependencies:
- spring-boot-starter-security: provides all the necessary dependencies to use Spring Security, including the core library, configuration, and other features, including authentication and authorization.
- spring-boot-starter-oauth2-client: provides support for OAuth2-based authentication and authorization.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
3.2. OAuth2 Client Configuration
In the application.properties file, add the following properties. We can access the property values in the “Client” section of the Keycloak admin console. Replace the client-id and client-secret values with the values for your Keycloak client. Also, replace the realm name as you configured in Keycloak.
A recommended approach is to store them as environment variables that can be accessed securely by the application at runtime. This helps to protect the client id and secret from being exposed in the source code, which could potentially lead to a security breach.
server.port=9090
spring.security.oauth2.client.registration.keycloak.client-id=employee-management-api
spring.security.oauth2.client.registration.keycloak.client-secret=--generated--
spring.security.oauth2.client.registration.keycloak.scope=openid
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.keycloak.redirect-uri=http://localhost:9090/login/oauth2/code/employee-management-api
spring.security.oauth2.client.provider.keycloak.issuer-uri=http://localhost:8180/realms/howtodoinjava-realm
The equivalent Java configuration is:
@Bean
public ClientRegistrationRepository clientRepository() {
ClientRegistration keycloak = keycloakClientRegistration();
return new InMemoryClientRegistrationRepository(keycloak);
}
private ClientRegistration keycloakClientRegistration() {
return ClientRegistration.withRegistrationId("howtodoinjava-realm")
.clientId("employee-management-api")
.clientSecret("--generated--")
.redirectUri("http://localhost:9090/login/oauth2/code/employee-management-api")
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.issuerUri("http://localhost:8180/realms/howtodoinjava-realm")
.authorizationUri("http://localhost:8080/realms/howtodoinjava/protocol/openid-connect/auth")
.tokenUri("http://localhost:8180/realms/howtodoinjava/protocol/openid-connect/token")
.userInfoUri("http://localhost:8180/realms/howtodoinjava/protocol/openid-connect/userinfo")
.build();
}
After detecting these properties, Spring boot auto-configuration will set up the necessary components to enable authentication/authorization with Keycloak (using OAuth2ClientAutoConfiguration
class ).
5.3. Spring Security
Currently, Spring Security still uses the default authentication workflow, including the default login page and the UsernamePasswordAuthenticationFilter. To change this behavior and force Spring Boot to use the OAuth2 protocol for login, we need to replace the .loginForm() method with .oauth2Login().
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeHttpRequests()
.requestMatchers("/public").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login();
return httpSecurity.build();
}
}
5.4. OAuth Client Registrations
Spring Security will automatically create a ClientRegistrationRepository
(by default InMemoryClientRegistrationRepository
instance to store ClientRegistration
objects in memory ) and register the client specified in the application.properties
file (in our case, keycloak).
The ClientRegistrationRepository
interface is part of Spring Security’s OAuth2 client support and it serves as a central repository for managing client registrations. It provides methods for retrieving the ClientRegistration object by their registration ID, getting a list of all registered clients, and adding or removing a client registration.
A ClientRegistration
interface represents a client registration with an OAuth2/OIDC provider such as Keycloak, Github, Google etc. It contains information such as the client ID, client secret, redirect URI, authorization grant type, issuer URI, token URI, and other properties needed for authenticating and authorizing with the provider.
The .oauth2Login()
method configures the application to use OAuth 2.0 for authentication. This method sets up the necessary configuration for the OAuth 2.0 login flow, including setting the authentication endpoint and callback URL. (It adds the OAuth2AuthorizationRequestRedirectFilter & OAuth2LoginAuthenticationFilter to the filter chain).
6. Test
Now let’s try to access one of the endpoints that we have in the EmployeeRestAPI /api/employees (protected endpoint), we will be redirected automatically to the login page of the keycloak server.

Provide the credentials of the user we just created (test-user/password), and you will be granted access to the endpoint and a successful response will be returned.

7. Authentication Flow
The following diagram depicts the process when a user requests a protected resource. Spring Security will redirect the user to Keycloak for authentication. After successful authentication, our backend will create a session for the user based on the information provided by Keycloak.

Here is the workflow of OAuth2 authentication using Spring Security and Keycloak, when a user sends a request to /api/employee
:
- The user sends a request to /api/employees.
- Spring Security (OAuth2 Filter) intercepts the request and checks if the user is authenticated. If not, Spring Security redirects the user to the Keycloak login page.
- The user enters their credentials on the Keycloak login page and submits the form.
- Keycloak verifies the user’s credentials and generates an authorization code, which is sent to the redirect URI.
- Spring Security requests Keycloak with the authorization code to get an access token.
- Keycloak returns the access token to our Spring Boot app.
- Spring Security requests the /user-info endpoint to get the user’s information.
- The session is created.
8. Conclusion
Integrating Spring Boot Security with OAuth2 client and Keycloak can greatly enhance the security of an application. With Keycloak as the identity provider, we can centralize the management of users and access control policies, while Spring Security provides a flexible and customizable framework for securing the application’s resources.
Through the use of the OAuth2 protocol, we can enable seamless and secure authentication and authorization flows, while also allowing for fine-grained control over access to specific resources.
Happy Learning !!