Allow configuration of logout through nested builder

Issue: gh-5557
This commit is contained in:
Eleftheria Stein
2019-06-19 12:55:26 -04:00
parent 43737a56bd
commit 92314b0956
3 changed files with 209 additions and 2 deletions

View File

@@ -37,10 +37,15 @@ import org.springframework.test.web.servlet.MockMvc;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
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.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
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.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -77,6 +82,26 @@ public class LogoutConfigurerTests {
}
}
@Test
public void configureWhenDefaultLogoutSuccessHandlerForHasNullLogoutHandlerInLambdaThenException() {
assertThatThrownBy(() -> this.spring.register(NullLogoutSuccessHandlerInLambdaConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullLogoutSuccessHandlerInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout(logout ->
logout.defaultLogoutSuccessHandlerFor(null, mock(RequestMatcher.class))
);
// @formatter:on
}
}
@Test
public void configureWhenDefaultLogoutSuccessHandlerForHasNullMatcherThenException() {
assertThatThrownBy(() -> this.spring.register(NullMatcherConfig.class).autowire())
@@ -96,6 +121,26 @@ public class LogoutConfigurerTests {
}
}
@Test
public void configureWhenDefaultLogoutSuccessHandlerForHasNullMatcherInLambdaThenException() {
assertThatThrownBy(() -> this.spring.register(NullMatcherInLambdaConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullMatcherInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout(logout ->
logout.defaultLogoutSuccessHandlerFor(mock(LogoutSuccessHandler.class), null)
);
// @formatter:on
}
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnLogoutFilter() {
this.spring.register(ObjectPostProcessorConfig.class).autowire();
@@ -263,6 +308,29 @@ public class LogoutConfigurerTests {
}
}
@Test
public void logoutWhenCustomLogoutUrlInLambdaThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledAndCustomLogoutInLambdaConfig.class).autowire();
this.mvc.perform(get("/custom/logout"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
}
@EnableWebSecurity
static class CsrfDisabledAndCustomLogoutInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.disable()
.logout(logout -> logout.logoutUrl("/custom/logout"));
// @formatter:on
}
}
// SEC-3170
@Test
public void configureWhenLogoutHandlerNullThenException() {
@@ -283,6 +351,24 @@ public class LogoutConfigurerTests {
}
}
@Test
public void configureWhenLogoutHandlerNullInLambdaThenException() {
assertThatThrownBy(() -> this.spring.register(NullLogoutHandlerInLambdaConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullLogoutHandlerInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout(logout -> logout.addLogoutHandler(null));
// @formatter:on
}
}
// SEC-3170
@Test
public void rememberMeWhenRememberMeServicesNotLogoutHandlerThenRedirectsToLogin() throws Exception {

View File

@@ -41,9 +41,11 @@ import org.springframework.test.web.servlet.ResultMatcher;
import static org.assertj.core.api.Assertions.assertThat;
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.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests to verify that all the functionality of <logout> attributes is present
@@ -83,6 +85,23 @@ public class NamespaceHttpLogoutTests {
}
}
@Test
@WithMockUser
public void logoutWhenDisabledInLambdaThenRespondsWithNotFound() throws Exception {
this.spring.register(HttpLogoutDisabledInLambdaConfig.class).autowire();
this.mvc.perform(post("/logout").with(csrf()).with(user("user")))
.andExpect(status().isNotFound());
}
@EnableWebSecurity
static class HttpLogoutDisabledInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.logout(AbstractHttpConfigurer::disable);
}
}
/**
* http/logout custom
*/
@@ -112,6 +131,35 @@ public class NamespaceHttpLogoutTests {
}
}
@Test
@WithMockUser
public void logoutWhenUsingVariousCustomizationsInLambdaThenMatchesNamespace() throws Exception {
this.spring.register(CustomHttpLogoutInLambdaConfig.class).autowire();
this.mvc.perform(post("/custom-logout").with(csrf()))
.andExpect(authenticated(false))
.andExpect(redirectedUrl("/logout-success"))
.andExpect(result -> assertThat(result.getResponse().getCookies()).hasSize(1))
.andExpect(cookie().maxAge("remove", 0))
.andExpect(session(Objects::nonNull));
}
@EnableWebSecurity
static class CustomHttpLogoutInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout(logout ->
logout.deleteCookies("remove")
.invalidateHttpSession(false)
.logoutUrl("/custom-logout")
.logoutSuccessUrl("/logout-success")
);
// @formatter:on
}
}
/**
* http/logout@success-handler-ref
*/
@@ -141,6 +189,32 @@ public class NamespaceHttpLogoutTests {
}
}
@Test
@WithMockUser
public void logoutWhenUsingSuccessHandlerRefInLambdaThenMatchesNamespace() throws Exception {
this.spring.register(SuccessHandlerRefHttpLogoutInLambdaConfig.class).autowire();
this.mvc.perform(post("/logout").with(csrf()))
.andExpect(authenticated(false))
.andExpect(redirectedUrl("/SuccessHandlerRefHttpLogoutConfig"))
.andExpect(noCookies())
.andExpect(session(Objects::isNull));
}
@EnableWebSecurity
static class SuccessHandlerRefHttpLogoutInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
SimpleUrlLogoutSuccessHandler logoutSuccessHandler = new SimpleUrlLogoutSuccessHandler();
logoutSuccessHandler.setDefaultTargetUrl("/SuccessHandlerRefHttpLogoutConfig");
// @formatter:off
http
.logout(logout -> logout.logoutSuccessHandler(logoutSuccessHandler));
// @formatter:on
}
}
ResultMatcher authenticated(boolean authenticated) {
return result -> assertThat(
Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())