Secure Spring Boot 3.1 with Keycloak: Step‑by‑Step Integration Guide
This tutorial shows how to integrate Keycloak 21.1.1 with Spring Boot 3.1 and Spring Security, covering realm and client setup, token acquisition, Maven dependencies, JWT configuration, a protected test endpoint, and verification of authentication behavior.
Preparation
The tutorial uses Spring Boot 3.1.0 and Keycloak 21.1.1. Other versions may require adjustments.
Configure Keycloak
1. Create a Realm and a Client in Keycloak.
2. Create a SYS_ADMIN role and assign it to a user.
3. Obtain an Access Token via Keycloak’s token endpoint, for example using curl:
curl --location 'http://localhost:9090/realms/MyAppRealm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=<YOUR_USER_NAME>' \
--data-urlencode 'password=<YOUR_USER_PASSWORD>' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=My-Awesome-App' \
--data-urlencode 'client_secret=<KEYCLOAK_CLIENT_SECRET>' \
--data-urlencode 'scope=openid'Save the returned Access Token for later use.
Configure Spring Boot Application
1. Create a Spring Boot project (refer to a Spring Boot tutorial if needed).
2. Add the following Maven dependency to pom.xml:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>3. Add JWT resource‑server settings to application.yml (or application.properties):
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:9090/realms/MyAppRealm
jwk-set-uri: http://localhost:9090/realms/MyAppRealm/protocol/openid-connect/certs4. Create a test controller with a protected endpoint:
@RequestMapping("/test")
@RestController
public class MySuperSecuredController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}5. Define a SecurityFilterChain bean to map JWT roles to Spring Security authorities:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeHttpRequests(registry -> registry
.requestMatchers("/test/**").hasRole("SYS_ADMIN")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2Configurer -> oauth2Configurer.jwt(jwtConfigurer ->
jwtConfigurer.jwtAuthenticationConverter(jwt -> {
Map<String, Collection<String>> realmAccess = jwt.getClaim("realm_access");
Collection<String> roles = realmAccess.get("roles");
var grantedAuthorities = roles.stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role))
.toList();
return new JwtAuthenticationToken(jwt, grantedAuthorities);
})
));
return httpSecurity.build();
}
}Verification
Start the Spring Boot application and ensure Keycloak is running.
Send a request to /test/hello:
If the Authorization header is missing, the server returns a 401 error.
If the header contains the previously obtained Access Token, the request succeeds and returns "hello".
Conclusion
Although Keycloak no longer provides dedicated Spring Security adapters, Spring Security’s built‑in OAuth2 and OIDC support makes integration straightforward once you understand how JWT tokens are processed.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
