Skip to content

Commit f6ddba8

Browse files
committed
Logout defaults to use Global SecurityContextServerLogoutHandler
Closes gh-8375
1 parent 566c25a commit f6ddba8

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -3738,7 +3738,8 @@ private HeaderSpec() {
37383738
*/
37393739
public final class LogoutSpec {
37403740
private LogoutWebFilter logoutWebFilter = new LogoutWebFilter();
3741-
private List<ServerLogoutHandler> logoutHandlers = new ArrayList<>(Arrays.asList(new SecurityContextServerLogoutHandler()));
3741+
private final SecurityContextServerLogoutHandler DEFAULT_LOGOUT_HANDLER = new SecurityContextServerLogoutHandler();
3742+
private List<ServerLogoutHandler> logoutHandlers = new ArrayList<>(Arrays.asList(this.DEFAULT_LOGOUT_HANDLER));
37423743

37433744
/**
37443745
* Configures the logout handler. Default is {@code SecurityContextServerLogoutHandler}
@@ -3802,6 +3803,10 @@ public ServerHttpSecurity disable() {
38023803
}
38033804

38043805
private ServerLogoutHandler createLogoutHandler() {
3806+
ServerSecurityContextRepository securityContextRepository = ServerHttpSecurity.this.securityContextRepository;
3807+
if (securityContextRepository != null) {
3808+
this.DEFAULT_LOGOUT_HANDLER.setSecurityContextRepository(securityContextRepository);
3809+
}
38053810
if (this.logoutHandlers.isEmpty()) {
38063811
return null;
38073812
} else if (this.logoutHandlers.size() == 1) {

config/src/test/java/org/springframework/security/config/web/server/LogoutSpecTests.java

+43
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.springframework.security.config.annotation.web.reactive.ServerHttpSecurityConfigurationBuilder;
2222
import org.springframework.security.htmlunit.server.WebTestClientHtmlUnitDriverBuilder;
2323
import org.springframework.security.web.server.SecurityWebFilterChain;
24+
import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
2425
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;
2526
import org.springframework.test.web.reactive.server.WebTestClient;
2627
import org.springframework.security.test.web.reactive.server.WebTestClientBuilder;
@@ -200,4 +201,46 @@ public void logoutWhenDisabledThenPostToLogoutDoesNothing() {
200201
homePage
201202
.assertAt();
202203
}
204+
205+
206+
@Test
207+
public void logoutWhenCustomSecurityContextRepositoryThenLogsOut() {
208+
WebSessionServerSecurityContextRepository repository = new WebSessionServerSecurityContextRepository();
209+
repository.setSpringSecurityContextAttrName("CUSTOM_CONTEXT_ATTR");
210+
SecurityWebFilterChain securityWebFilter = this.http
211+
.securityContextRepository(repository)
212+
.authorizeExchange()
213+
.anyExchange().authenticated()
214+
.and()
215+
.formLogin()
216+
.and()
217+
.logout()
218+
.and()
219+
.build();
220+
221+
WebTestClient webTestClient = WebTestClientBuilder
222+
.bindToWebFilters(securityWebFilter)
223+
.build();
224+
225+
WebDriver driver = WebTestClientHtmlUnitDriverBuilder
226+
.webTestClientSetup(webTestClient)
227+
.build();
228+
229+
FormLoginTests.DefaultLoginPage loginPage = FormLoginTests.HomePage.to(driver, FormLoginTests.DefaultLoginPage.class)
230+
.assertAt();
231+
232+
FormLoginTests.HomePage homePage = loginPage.loginForm()
233+
.username("user")
234+
.password("password")
235+
.submit(FormLoginTests.HomePage.class);
236+
237+
homePage.assertAt();
238+
239+
FormLoginTests.DefaultLogoutPage.to(driver)
240+
.assertAt()
241+
.logout();
242+
243+
FormLoginTests.HomePage.to(driver, FormLoginTests.DefaultLoginPage.class)
244+
.assertAt();
245+
}
203246
}

config/src/test/java/org/springframework/security/config/web/server/OAuth2LoginTests.java

+3
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
8484
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
8585
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
86+
import org.springframework.security.web.server.authentication.logout.SecurityContextServerLogoutHandler;
8687
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
8788
import org.springframework.security.web.server.savedrequest.ServerRequestCache;
8889
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
@@ -716,6 +717,8 @@ public SecurityWebFilterChain springSecurity(ServerHttpSecurity http) {
716717
http
717718
.csrf().disable()
718719
.logout()
720+
// avoid using mock ServerSecurityContextRepository for logout
721+
.logoutHandler(new SecurityContextServerLogoutHandler())
719722
.logoutSuccessHandler(
720723
new OidcClientInitiatedServerLogoutSuccessHandler(
721724
new InMemoryReactiveClientRegistrationRepository(this.withLogout)))

0 commit comments

Comments
 (0)