Disable default logout page when logout disabled

Closes gh-9475
This commit is contained in:
Eleftheria Stein 2021-06-17 16:17:27 +02:00
parent 7cf538cba6
commit 442c9cbf38
4 changed files with 81 additions and 15 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -100,7 +100,10 @@ public final class DefaultLoginPageConfigurer<H extends HttpSecurityBuilder<H>>
if (loginPageGeneratingFilter.isEnabled() && authenticationEntryPoint == null) { if (loginPageGeneratingFilter.isEnabled() && authenticationEntryPoint == null) {
loginPageGeneratingFilter = postProcess(loginPageGeneratingFilter); loginPageGeneratingFilter = postProcess(loginPageGeneratingFilter);
http.addFilter(loginPageGeneratingFilter); http.addFilter(loginPageGeneratingFilter);
http.addFilter(this.logoutPageGeneratingFilter); LogoutConfigurer<H> logoutConfigurer = http.getConfigurer(LogoutConfigurer.class);
if (logoutConfigurer != null) {
http.addFilter(this.logoutPageGeneratingFilter);
}
} }
} }

View File

@ -3264,7 +3264,10 @@ public class ServerHttpSecurity {
} }
if (loginPage != null) { if (loginPage != null) {
http.addFilterAt(loginPage, SecurityWebFiltersOrder.LOGIN_PAGE_GENERATING); http.addFilterAt(loginPage, SecurityWebFiltersOrder.LOGIN_PAGE_GENERATING);
http.addFilterAt(new LogoutPageGeneratingWebFilter(), SecurityWebFiltersOrder.LOGOUT_PAGE_GENERATING); if (http.logout != null) {
http.addFilterAt(new LogoutPageGeneratingWebFilter(),
SecurityWebFiltersOrder.LOGOUT_PAGE_GENERATING);
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -44,11 +44,14 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.springframework.security.config.Customizer.withDefaults;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/** /**
* Tests for {@link DefaultLoginPageConfigurer} * Tests for {@link DefaultLoginPageConfigurer}
@ -217,6 +220,18 @@ public class DefaultLoginPageConfigurerTests {
)); ));
} }
@Test
public void formLoginWhenLogoutEnabledThenCreatesDefaultLogoutPage() throws Exception {
this.spring.register(DefaultLogoutPageConfig.class).autowire();
this.mvc.perform(get("/logout").with(user("user"))).andExpect(status().isOk());
}
@Test
public void formLoginWhenLogoutDisabledThenDefaultLogoutPageDoesNotExist() throws Exception {
this.spring.register(LogoutDisabledConfig.class).autowire();
this.mvc.perform(get("/logout").with(user("user"))).andExpect(status().isNotFound());
}
@EnableWebSecurity @EnableWebSecurity
static class DefaultLoginPageConfig extends WebSecurityConfigurerAdapter { static class DefaultLoginPageConfig extends WebSecurityConfigurerAdapter {
@Override @Override
@ -552,6 +567,41 @@ public class DefaultLoginPageConfigurerTests {
} }
} }
@EnableWebSecurity
static class DefaultLogoutPageConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.formLogin(withDefaults());
// @formatter:on
}
}
@EnableWebSecurity
static class LogoutDisabledConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.formLogin(withDefaults())
.logout((logout) -> logout
.disable()
);
// @formatter:on
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> { static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override @Override
public <O> O postProcess(O object) { public <O> O postProcess(O object) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,7 +25,10 @@ import org.springframework.security.web.server.context.WebSessionServerSecurityC
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.security.test.web.reactive.server.WebTestClientBuilder; import org.springframework.security.test.web.reactive.server.WebTestClientBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.config.Customizer.withDefaults;
/** /**
@ -167,7 +170,8 @@ public class LogoutSpecTests {
} }
@Test @Test
public void logoutWhenDisabledThenPostToLogoutDoesNothing() { public void logoutWhenDisabledThenDefaultLogoutPageDoesNotExist() {
// @formatter:off
SecurityWebFilterChain securityWebFilter = this.http SecurityWebFilterChain securityWebFilter = this.http
.authorizeExchange() .authorizeExchange()
.anyExchange().authenticated() .anyExchange().authenticated()
@ -177,7 +181,7 @@ public class LogoutSpecTests {
.build(); .build();
WebTestClient webTestClient = WebTestClientBuilder WebTestClient webTestClient = WebTestClientBuilder
.bindToWebFilters(securityWebFilter) .bindToControllerAndWebFilters(HomeController.class, securityWebFilter)
.build(); .build();
WebDriver driver = WebTestClientHtmlUnitDriverBuilder WebDriver driver = WebTestClientHtmlUnitDriverBuilder
@ -191,15 +195,10 @@ public class LogoutSpecTests {
.username("user") .username("user")
.password("password") .password("password")
.submit(FormLoginTests.HomePage.class); .submit(FormLoginTests.HomePage.class);
// @formatter:on
homePage.assertAt(); homePage.assertAt();
FormLoginTests.DefaultLogoutPage.to(driver);
FormLoginTests.DefaultLogoutPage.to(driver) assertThat(driver.getPageSource()).isEmpty();
.assertAt()
.logout();
homePage
.assertAt();
} }
@ -243,4 +242,15 @@ public class LogoutSpecTests {
FormLoginTests.HomePage.to(driver, FormLoginTests.DefaultLoginPage.class) FormLoginTests.HomePage.to(driver, FormLoginTests.DefaultLoginPage.class)
.assertAt(); .assertAt();
} }
@RestController
public static class HomeController {
@GetMapping("/")
public String ok() {
return "ok";
}
}
} }