diff --git a/spring-boot-modules/spring-boot-keycloak/pom.xml b/spring-boot-modules/spring-boot-keycloak/pom.xml
index 9e39176765..4f30d32bec 100644
--- a/spring-boot-modules/spring-boot-keycloak/pom.xml
+++ b/spring-boot-modules/spring-boot-keycloak/pom.xml
@@ -47,6 +47,10 @@
spring-boot-starter-test
test
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-client
+
org.springframework.boot
spring-boot-starter-security
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/KeycloakLogoutHandler.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/KeycloakLogoutHandler.java
new file mode 100644
index 0000000000..06c41e9b1d
--- /dev/null
+++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/KeycloakLogoutHandler.java
@@ -0,0 +1,45 @@
+package com.baeldung.keycloak;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.core.oidc.user.OidcUser;
+import org.springframework.security.web.authentication.logout.LogoutHandler;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Component
+public class KeycloakLogoutHandler implements LogoutHandler {
+
+ private static final Logger logger = LoggerFactory.getLogger(KeycloakLogoutHandler.class);
+ private final RestTemplate restTemplate;
+
+ public KeycloakLogoutHandler(RestTemplate restTemplate) {
+ this.restTemplate = restTemplate;
+ }
+
+ @Override
+ public void logout(HttpServletRequest request, HttpServletResponse response, Authentication auth) {
+ logoutFromKeycloak((OidcUser) auth.getPrincipal());
+ }
+
+ private void logoutFromKeycloak(OidcUser user) {
+ String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";
+ UriComponentsBuilder builder = UriComponentsBuilder
+ .fromUriString(endSessionEndpoint)
+ .queryParam("id_token_hint", user.getIdToken().getTokenValue());
+
+ ResponseEntity logoutResponse = restTemplate.getForEntity(builder.toUriString(), String.class);
+ if (logoutResponse.getStatusCode().is2xxSuccessful()) {
+ logger.info("Successfulley logged out from Keycloak");
+ } else {
+ logger.error("Could not propagate logout to Keycloak");
+ }
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java
index 826f475a6e..88f829e567 100644
--- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java
+++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java
@@ -1,42 +1,41 @@
package com.baeldung.keycloak;
-import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
-import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
-import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
-import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
-@KeycloakConfiguration
-class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
- // Submits the KeycloakAuthenticationProvider to the AuthenticationManager
- @Autowired
- public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
- KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
- keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
- auth.authenticationProvider(keycloakAuthenticationProvider);
+@Configuration
+@EnableWebSecurity
+class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ private final KeycloakLogoutHandler keycloakLogoutHandler;
+
+ SecurityConfig(KeycloakLogoutHandler keycloakLogoutHandler) {
+ this.keycloakLogoutHandler = keycloakLogoutHandler;
}
- // Specifies the session authentication strategy
@Bean
- @Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
- super.configure(http);
http.authorizeRequests()
- .antMatchers("/customers*", "/users*")
- .hasRole("user")
- .anyRequest()
- .permitAll();
+ .antMatchers("/customers*", "/users*")
+ .hasRole("USER")
+ .anyRequest()
+ .permitAll();
+ http.oauth2Login()
+ .and()
+ .logout()
+ .addLogoutHandler(keycloakLogoutHandler)
+ .logoutSuccessUrl("/");
}
+
}
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SpringBoot.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SpringBoot.java
index d67dd05fc7..90d7e774a4 100644
--- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SpringBoot.java
+++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SpringBoot.java
@@ -2,6 +2,8 @@ package com.baeldung.keycloak;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@@ -11,4 +13,8 @@ public class SpringBoot {
SpringApplication.run(SpringBoot.class, args);
}
+ @Bean
+ public RestTemplate restTemplate() {
+ return new RestTemplate();
+ }
}
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/resources/application.properties b/spring-boot-modules/spring-boot-keycloak/src/main/resources/application.properties
index 9dfd3ea720..323617e2ef 100644
--- a/spring-boot-modules/spring-boot-keycloak/src/main/resources/application.properties
+++ b/spring-boot-modules/spring-boot-keycloak/src/main/resources/application.properties
@@ -6,6 +6,10 @@ keycloak.auth-server-url=http://localhost:8180/auth
keycloak.realm=SpringBootKeycloak
keycloak.resource=login-app
keycloak.public-client=true
-#keycloak.security-constraints[0].authRoles[0]=user
-#keycloak.security-constraints[0].securityCollections[0].patterns[0]=/customers/*
-keycloak.principal-attribute=preferred_username
\ No newline at end of file
+keycloak.principal-attribute=preferred_username
+
+spring.security.oauth2.client.registration.keycloak.client-id=login-app
+spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
+spring.security.oauth2.client.registration.keycloak.scope=openid
+spring.security.oauth2.client.provider.keycloak.issuer-uri=http://localhost:8180/auth/realms/SpringBootKeycloak
+spring.security.oauth2.client.provider.keycloak.user-name-attribute=preferred_username
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/SpringContextTest.java b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/SpringContextTest.java
deleted file mode 100644
index 3f3ecd87d0..0000000000
--- a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/SpringContextTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.baeldung;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import com.baeldung.keycloak.SpringBoot;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest(classes = SpringBoot.class)
-public class SpringContextTest {
-
- @Test
- public void whenSpringContextIsBootstrapped_thenNoExceptions() {
- }
-}