Skip to content

Commit 442c9cb

Browse files
committed
Disable default logout page when logout disabled
Closes gh-9475
1 parent 7cf538c commit 442c9cb

File tree

4 files changed

+81
-15
lines changed

4 files changed

+81
-15
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurer.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -100,7 +100,10 @@ public void configure(H http) {
100100
if (loginPageGeneratingFilter.isEnabled() && authenticationEntryPoint == null) {
101101
loginPageGeneratingFilter = postProcess(loginPageGeneratingFilter);
102102
http.addFilter(loginPageGeneratingFilter);
103-
http.addFilter(this.logoutPageGeneratingFilter);
103+
LogoutConfigurer<H> logoutConfigurer = http.getConfigurer(LogoutConfigurer.class);
104+
if (logoutConfigurer != null) {
105+
http.addFilter(this.logoutPageGeneratingFilter);
106+
}
104107
}
105108
}
106109

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -3264,7 +3264,10 @@ protected void configure(ServerHttpSecurity http) {
32643264
}
32653265
if (loginPage != null) {
32663266
http.addFilterAt(loginPage, SecurityWebFiltersOrder.LOGIN_PAGE_GENERATING);
3267-
http.addFilterAt(new LogoutPageGeneratingWebFilter(), SecurityWebFiltersOrder.LOGOUT_PAGE_GENERATING);
3267+
if (http.logout != null) {
3268+
http.addFilterAt(new LogoutPageGeneratingWebFilter(),
3269+
SecurityWebFiltersOrder.LOGOUT_PAGE_GENERATING);
3270+
}
32683271
}
32693272
}
32703273

config/src/test/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurerTests.java

+51-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -44,11 +44,14 @@
4444
import static org.mockito.ArgumentMatchers.any;
4545
import static org.mockito.Mockito.spy;
4646
import static org.mockito.Mockito.verify;
47+
import static org.springframework.security.config.Customizer.withDefaults;
4748
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
49+
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
4850
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
4951
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
5052
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
5153
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
54+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
5255

5356
/**
5457
* Tests for {@link DefaultLoginPageConfigurer}
@@ -217,6 +220,18 @@ public void loginPageWhenLoggedOutThenDefaultLoginPageWithLogoutMessage() throws
217220
));
218221
}
219222

223+
@Test
224+
public void formLoginWhenLogoutEnabledThenCreatesDefaultLogoutPage() throws Exception {
225+
this.spring.register(DefaultLogoutPageConfig.class).autowire();
226+
this.mvc.perform(get("/logout").with(user("user"))).andExpect(status().isOk());
227+
}
228+
229+
@Test
230+
public void formLoginWhenLogoutDisabledThenDefaultLogoutPageDoesNotExist() throws Exception {
231+
this.spring.register(LogoutDisabledConfig.class).autowire();
232+
this.mvc.perform(get("/logout").with(user("user"))).andExpect(status().isNotFound());
233+
}
234+
220235
@EnableWebSecurity
221236
static class DefaultLoginPageConfig extends WebSecurityConfigurerAdapter {
222237
@Override
@@ -552,6 +567,41 @@ static ObjectPostProcessor<Object> objectPostProcessor() {
552567
}
553568
}
554569

570+
@EnableWebSecurity
571+
static class DefaultLogoutPageConfig extends WebSecurityConfigurerAdapter {
572+
573+
@Override
574+
protected void configure(HttpSecurity http) throws Exception {
575+
// @formatter:off
576+
http
577+
.authorizeRequests((authorize) -> authorize
578+
.anyRequest().authenticated()
579+
)
580+
.formLogin(withDefaults());
581+
// @formatter:on
582+
}
583+
584+
}
585+
586+
@EnableWebSecurity
587+
static class LogoutDisabledConfig extends WebSecurityConfigurerAdapter {
588+
589+
@Override
590+
protected void configure(HttpSecurity http) throws Exception {
591+
// @formatter:off
592+
http
593+
.authorizeRequests((authorize) -> authorize
594+
.anyRequest().authenticated()
595+
)
596+
.formLogin(withDefaults())
597+
.logout((logout) -> logout
598+
.disable()
599+
);
600+
// @formatter:on
601+
}
602+
603+
}
604+
555605
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
556606
@Override
557607
public <O> O postProcess(O object) {

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

+21-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,7 +25,10 @@
2525
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;
2626
import org.springframework.test.web.reactive.server.WebTestClient;
2727
import org.springframework.security.test.web.reactive.server.WebTestClientBuilder;
28+
import org.springframework.web.bind.annotation.GetMapping;
29+
import org.springframework.web.bind.annotation.RestController;
2830

31+
import static org.assertj.core.api.Assertions.assertThat;
2932
import static org.springframework.security.config.Customizer.withDefaults;
3033

3134
/**
@@ -167,7 +170,8 @@ public void logoutWhenCustomLogoutInLambdaThenCustomLogoutUsed() {
167170
}
168171

169172
@Test
170-
public void logoutWhenDisabledThenPostToLogoutDoesNothing() {
173+
public void logoutWhenDisabledThenDefaultLogoutPageDoesNotExist() {
174+
// @formatter:off
171175
SecurityWebFilterChain securityWebFilter = this.http
172176
.authorizeExchange()
173177
.anyExchange().authenticated()
@@ -177,7 +181,7 @@ public void logoutWhenDisabledThenPostToLogoutDoesNothing() {
177181
.build();
178182

179183
WebTestClient webTestClient = WebTestClientBuilder
180-
.bindToWebFilters(securityWebFilter)
184+
.bindToControllerAndWebFilters(HomeController.class, securityWebFilter)
181185
.build();
182186

183187
WebDriver driver = WebTestClientHtmlUnitDriverBuilder
@@ -191,15 +195,10 @@ public void logoutWhenDisabledThenPostToLogoutDoesNothing() {
191195
.username("user")
192196
.password("password")
193197
.submit(FormLoginTests.HomePage.class);
194-
198+
// @formatter:on
195199
homePage.assertAt();
196-
197-
FormLoginTests.DefaultLogoutPage.to(driver)
198-
.assertAt()
199-
.logout();
200-
201-
homePage
202-
.assertAt();
200+
FormLoginTests.DefaultLogoutPage.to(driver);
201+
assertThat(driver.getPageSource()).isEmpty();
203202
}
204203

205204

@@ -243,4 +242,15 @@ public void logoutWhenCustomSecurityContextRepositoryThenLogsOut() {
243242
FormLoginTests.HomePage.to(driver, FormLoginTests.DefaultLoginPage.class)
244243
.assertAt();
245244
}
245+
246+
@RestController
247+
public static class HomeController {
248+
249+
@GetMapping("/")
250+
public String ok() {
251+
return "ok";
252+
}
253+
254+
}
255+
246256
}

0 commit comments

Comments
 (0)