2 changed files with 375 additions and 270 deletions
@ -1,270 +0,0 @@
@@ -1,270 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2013 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.security.config.annotation.web.configurers |
||||
|
||||
import org.springframework.http.HttpStatus |
||||
import org.springframework.http.MediaType |
||||
import org.springframework.security.config.annotation.AnyObjectPostProcessor |
||||
import org.springframework.security.config.annotation.BaseSpringSpec |
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity |
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity |
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter |
||||
import org.springframework.security.web.authentication.RememberMeServices |
||||
import org.springframework.security.web.authentication.logout.LogoutFilter |
||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler |
||||
import org.springframework.security.web.util.matcher.RequestMatcher |
||||
|
||||
/** |
||||
* |
||||
* @author Rob Winch |
||||
*/ |
||||
class LogoutConfigurerTests extends BaseSpringSpec { |
||||
|
||||
def defaultLogoutSuccessHandlerForNullLogoutHandler() { |
||||
setup: |
||||
LogoutConfigurer config = new LogoutConfigurer(); |
||||
when: |
||||
config.defaultLogoutSuccessHandlerFor(null, Mock(RequestMatcher)) |
||||
then: |
||||
thrown(IllegalArgumentException) |
||||
} |
||||
|
||||
def defaultLogoutSuccessHandlerForNullMatcher() { |
||||
setup: |
||||
LogoutConfigurer config = new LogoutConfigurer(); |
||||
when: |
||||
config.defaultLogoutSuccessHandlerFor(Mock(LogoutSuccessHandler), null) |
||||
then: |
||||
thrown(IllegalArgumentException) |
||||
} |
||||
|
||||
def "logout ObjectPostProcessor"() { |
||||
setup: |
||||
AnyObjectPostProcessor opp = Mock() |
||||
HttpSecurity http = new HttpSecurity(opp, authenticationBldr, [:]) |
||||
when: |
||||
http |
||||
.logout() |
||||
.and() |
||||
.build() |
||||
|
||||
then: "LogoutFilter is registered with LifecycleManager" |
||||
1 * opp.postProcess(_ as LogoutFilter) >> {LogoutFilter o -> o} |
||||
} |
||||
|
||||
def "invoke logout twice does not override"() { |
||||
when: |
||||
loadConfig(InvokeTwiceDoesNotOverride) |
||||
request.method = "POST" |
||||
request.servletPath = "/custom/logout" |
||||
findFilter(LogoutFilter).doFilter(request,response,chain) |
||||
then: |
||||
response.redirectedUrl == "/login?logout" |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class InvokeTwiceDoesNotOverride extends WebSecurityConfigurerAdapter { |
||||
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.logout() |
||||
.logoutUrl("/custom/logout") |
||||
.and() |
||||
.logout() |
||||
} |
||||
} |
||||
|
||||
def "Logout allows other methods if CSRF is disabled"() { |
||||
when: |
||||
loadConfig(CsrfDisabledConfig) |
||||
request.method = method |
||||
request.servletPath = "/logout" |
||||
findFilter(LogoutFilter).doFilter(request,response,chain) |
||||
then: |
||||
response.status == httpStatus.value() |
||||
response.redirectedUrl == url |
||||
where: |
||||
method | httpStatus | url |
||||
"GET" | HttpStatus.FOUND | "/login?logout" |
||||
"POST" | HttpStatus.FOUND | "/login?logout" |
||||
"PUT" | HttpStatus.FOUND | "/login?logout" |
||||
"DELETE" | HttpStatus.FOUND | "/login?logout" |
||||
"OPTIONS" | HttpStatus.OK | null |
||||
"HEAD" | HttpStatus.OK | null |
||||
"TRACE" | HttpStatus.OK | null |
||||
|
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class CsrfDisabledConfig extends WebSecurityConfigurerAdapter { |
||||
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.csrf().disable() |
||||
.logout() |
||||
} |
||||
} |
||||
|
||||
|
||||
def "Logout allows other methods if CSRF is disabled with custom logout URL"() { |
||||
when: |
||||
loadConfig(CsrfDisabledCustomLogoutUrlConfig) |
||||
request.method = method |
||||
request.servletPath = "/custom/logout" |
||||
findFilter(LogoutFilter).doFilter(request,response,chain) |
||||
then: |
||||
response.status == httpStatus.value() |
||||
response.redirectedUrl == url |
||||
where: |
||||
method | httpStatus | url |
||||
"GET" | HttpStatus.FOUND | "/login?logout" |
||||
"POST" | HttpStatus.FOUND | "/login?logout" |
||||
"PUT" | HttpStatus.FOUND | "/login?logout" |
||||
"DELETE" | HttpStatus.FOUND | "/login?logout" |
||||
"OPTIONS" | HttpStatus.OK | null |
||||
"HEAD" | HttpStatus.OK | null |
||||
"TRACE" | HttpStatus.OK | null |
||||
|
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class CsrfDisabledCustomLogoutUrlConfig extends WebSecurityConfigurerAdapter { |
||||
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.logout() |
||||
.logoutUrl("/custom/logout") |
||||
.and() |
||||
.csrf().disable() |
||||
} |
||||
} |
||||
|
||||
def "SEC-3170: LogoutConfigurer RememberMeService not LogoutHandler"() { |
||||
setup: |
||||
RememberMeNoLogoutHandler.REMEMBER_ME = Mock(RememberMeServices) |
||||
loadConfig(RememberMeNoLogoutHandler) |
||||
request.method = "POST" |
||||
request.servletPath = "/logout" |
||||
when: |
||||
findFilter(LogoutFilter).doFilter(request,response,chain) |
||||
then: |
||||
response.redirectedUrl == "/login?logout" |
||||
} |
||||
|
||||
def "SEC-3170: LogoutConfigurer prevents null LogoutHandler"() { |
||||
when: |
||||
new LogoutConfigurer().addLogoutHandler(null) |
||||
then: |
||||
thrown(IllegalArgumentException) |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class RememberMeNoLogoutHandler extends WebSecurityConfigurerAdapter { |
||||
static RememberMeServices REMEMBER_ME |
||||
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http |
||||
.rememberMe() |
||||
.rememberMeServices(REMEMBER_ME) |
||||
} |
||||
} |
||||
|
||||
def "LogoutConfigurer content negotiation text/html redirects"() { |
||||
setup: |
||||
loadConfig(LogoutHandlerContentNegotiation) |
||||
when: |
||||
login() |
||||
request.method = 'POST' |
||||
request.servletPath = '/logout' |
||||
request.addHeader('Accept', 'text/html') |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == 302 |
||||
response.redirectedUrl == '/login?logout' |
||||
} |
||||
|
||||
// gh-3282 |
||||
def "LogoutConfigurer content negotiation json 201"() { |
||||
setup: |
||||
loadConfig(LogoutHandlerContentNegotiation) |
||||
when: |
||||
login() |
||||
request.method = 'POST' |
||||
request.servletPath = '/logout' |
||||
request.addHeader('Accept', 'application/json') |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == 204 |
||||
} |
||||
|
||||
// gh-4831 |
||||
def "LogoutConfigurer content negotiation all 201"() { |
||||
setup: |
||||
loadConfig(LogoutHandlerContentNegotiation) |
||||
when: |
||||
login() |
||||
request.method = 'POST' |
||||
request.servletPath = '/logout' |
||||
request.addHeader('Accept', MediaType.ALL_VALUE) |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == 204 |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class LogoutHandlerContentNegotiation extends WebSecurityConfigurerAdapter { |
||||
} |
||||
// gh-3902 |
||||
def "logout in chrome is 302"() { |
||||
setup: |
||||
loadConfig(LogoutHandlerContentNegotiationForChrome) |
||||
when: |
||||
login() |
||||
request.method = 'POST' |
||||
request.servletPath = '/logout' |
||||
request.addHeader('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8') |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == 302 |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class LogoutHandlerContentNegotiationForChrome extends WebSecurityConfigurerAdapter { |
||||
} |
||||
|
||||
// gh-3997 |
||||
def "LogoutConfigurer for XMLHttpRequest is 204"() { |
||||
setup: |
||||
loadConfig(LogoutXMLHttpRequestConfig) |
||||
when: |
||||
login() |
||||
request.method = 'POST' |
||||
request.servletPath = '/logout' |
||||
request.addHeader('Accept', 'text/html,application/json') |
||||
request.addHeader('X-Requested-With', 'XMLHttpRequest') |
||||
springSecurityFilterChain.doFilter(request,response,chain) |
||||
then: |
||||
response.status == 204 |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class LogoutXMLHttpRequestConfig extends WebSecurityConfigurerAdapter { |
||||
} |
||||
} |
||||
@ -0,0 +1,375 @@
@@ -0,0 +1,375 @@
|
||||
/* |
||||
* Copyright 2002-2019 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.config.annotation.web.configurers; |
||||
|
||||
import org.apache.http.HttpHeaders; |
||||
import org.junit.Rule; |
||||
import org.junit.Test; |
||||
import org.springframework.beans.factory.BeanCreationException; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.security.config.annotation.ObjectPostProcessor; |
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
||||
import org.springframework.security.config.test.SpringTestRule; |
||||
import org.springframework.security.web.authentication.RememberMeServices; |
||||
import org.springframework.security.web.authentication.logout.LogoutFilter; |
||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; |
||||
import org.springframework.security.web.util.matcher.RequestMatcher; |
||||
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.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.result.MockMvcResultMatchers.redirectedUrl; |
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
||||
|
||||
/** |
||||
* Tests for {@link LogoutConfigurer} |
||||
* |
||||
* @author Rob Winch |
||||
* @author Eleftheria Stein |
||||
*/ |
||||
public class LogoutConfigurerTests { |
||||
|
||||
@Rule |
||||
public final SpringTestRule spring = new SpringTestRule(); |
||||
|
||||
@Autowired |
||||
MockMvc mvc; |
||||
|
||||
@Test |
||||
public void configureWhenDefaultLogoutSuccessHandlerForHasNullLogoutHandlerThenException() { |
||||
assertThatThrownBy(() -> this.spring.register(NullLogoutSuccessHandlerConfig.class).autowire()) |
||||
.isInstanceOf(BeanCreationException.class) |
||||
.hasRootCauseInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class NullLogoutSuccessHandlerConfig extends WebSecurityConfigurerAdapter { |
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
// @formatter:off
|
||||
http |
||||
.logout() |
||||
.defaultLogoutSuccessHandlerFor(null, mock(RequestMatcher.class)); |
||||
// @formatter:on
|
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void configureWhenDefaultLogoutSuccessHandlerForHasNullMatcherThenException() { |
||||
assertThatThrownBy(() -> this.spring.register(NullMatcherConfig.class).autowire()) |
||||
.isInstanceOf(BeanCreationException.class) |
||||
.hasRootCauseInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class NullMatcherConfig extends WebSecurityConfigurerAdapter { |
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
// @formatter:off
|
||||
http |
||||
.logout() |
||||
.defaultLogoutSuccessHandlerFor(mock(LogoutSuccessHandler.class), null); |
||||
// @formatter:on
|
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnLogoutFilter() { |
||||
this.spring.register(ObjectPostProcessorConfig.class).autowire(); |
||||
|
||||
verify(ObjectPostProcessorConfig.objectPostProcessor) |
||||
.postProcess(any(LogoutFilter.class)); |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter { |
||||
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class); |
||||
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
// @formatter:off
|
||||
http |
||||
.logout(); |
||||
// @formatter:on
|
||||
} |
||||
|
||||
@Bean |
||||
static ObjectPostProcessor<Object> objectPostProcessor() { |
||||
return objectPostProcessor; |
||||
} |
||||
} |
||||
|
||||
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> { |
||||
@Override |
||||
public <O> O postProcess(O object) { |
||||
return object; |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void logoutWhenInvokedTwiceThenUsesOriginalLogoutUrl() throws Exception { |
||||
this.spring.register(DuplicateDoesNotOverrideConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(post("/custom/logout") |
||||
.with(csrf())) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class DuplicateDoesNotOverrideConfig extends WebSecurityConfigurerAdapter { |
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
// @formatter:off
|
||||
http |
||||
.logout() |
||||
.logoutUrl("/custom/logout") |
||||
.and() |
||||
.logout(); |
||||
// @formatter:on
|
||||
} |
||||
|
||||
@Override |
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
||||
// @formatter:off
|
||||
auth |
||||
.inMemoryAuthentication(); |
||||
// @formatter:on
|
||||
} |
||||
} |
||||
|
||||
// SEC-2311
|
||||
@Test |
||||
public void logoutWhenGetRequestAndCsrfDisabledThenRedirectsToLogin() throws Exception { |
||||
this.spring.register(CsrfDisabledConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(get("/logout")) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
@Test |
||||
public void logoutWhenPostRequestAndCsrfDisabledThenRedirectsToLogin() throws Exception { |
||||
this.spring.register(CsrfDisabledConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(post("/logout")) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
@Test |
||||
public void logoutWhenPutRequestAndCsrfDisabledThenRedirectsToLogin() throws Exception { |
||||
this.spring.register(CsrfDisabledConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(put("/logout")) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
@Test |
||||
public void logoutWhenDeleteRequestAndCsrfDisabledThenRedirectsToLogin() throws Exception { |
||||
this.spring.register(CsrfDisabledConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(delete("/logout")) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class CsrfDisabledConfig extends WebSecurityConfigurerAdapter { |
||||
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
// @formatter:off
|
||||
http |
||||
.csrf() |
||||
.disable() |
||||
.logout(); |
||||
// @formatter:on
|
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void logoutWhenGetRequestAndCsrfDisabledAndCustomLogoutUrlThenRedirectsToLogin() throws Exception { |
||||
this.spring.register(CsrfDisabledAndCustomLogoutConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(get("/custom/logout")) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
@Test |
||||
public void logoutWhenPostRequestAndCsrfDisabledAndCustomLogoutUrlThenRedirectsToLogin() throws Exception { |
||||
this.spring.register(CsrfDisabledAndCustomLogoutConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(post("/custom/logout")) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
@Test |
||||
public void logoutWhenPutRequestAndCsrfDisabledAndCustomLogoutUrlThenRedirectsToLogin() throws Exception { |
||||
this.spring.register(CsrfDisabledAndCustomLogoutConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(put("/custom/logout")) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
@Test |
||||
public void logoutWhenDeleteRequestAndCsrfDisabledAndCustomLogoutUrlThenRedirectsToLogin() throws Exception { |
||||
this.spring.register(CsrfDisabledAndCustomLogoutConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(delete("/custom/logout")) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class CsrfDisabledAndCustomLogoutConfig extends WebSecurityConfigurerAdapter { |
||||
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
// @formatter:off
|
||||
http |
||||
.csrf() |
||||
.disable() |
||||
.logout() |
||||
.logoutUrl("/custom/logout"); |
||||
// @formatter:on
|
||||
} |
||||
} |
||||
|
||||
// SEC-3170
|
||||
@Test |
||||
public void configureWhenLogoutHandlerNullThenException() { |
||||
assertThatThrownBy(() -> this.spring.register(NullLogoutHandlerConfig.class).autowire()) |
||||
.isInstanceOf(BeanCreationException.class) |
||||
.hasRootCauseInstanceOf(IllegalArgumentException.class); |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class NullLogoutHandlerConfig extends WebSecurityConfigurerAdapter { |
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
// @formatter:off
|
||||
http |
||||
.logout() |
||||
.addLogoutHandler(null); |
||||
// @formatter:on
|
||||
} |
||||
} |
||||
|
||||
// SEC-3170
|
||||
@Test |
||||
public void rememberMeWhenRememberMeServicesNotLogoutHandlerThenRedirectsToLogin() throws Exception { |
||||
this.spring.register(RememberMeNoLogoutHandler.class).autowire(); |
||||
|
||||
this.mvc.perform(post("/logout") |
||||
.with(csrf())) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class RememberMeNoLogoutHandler extends WebSecurityConfigurerAdapter { |
||||
static RememberMeServices REMEMBER_ME = mock(RememberMeServices.class); |
||||
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
// @formatter:off
|
||||
http |
||||
.rememberMe() |
||||
.rememberMeServices(REMEMBER_ME); |
||||
// @formatter:on
|
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void logoutWhenAcceptTextHtmlThenRedirectsToLogin() throws Exception { |
||||
this.spring.register(BasicSecurityConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(post("/logout") |
||||
.with(csrf()) |
||||
.with(user("user")) |
||||
.header(HttpHeaders.ACCEPT, MediaType.TEXT_HTML_VALUE)) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
// gh-3282
|
||||
@Test |
||||
public void logoutWhenAcceptApplicationJsonThenReturnsStatusNoContent() throws Exception { |
||||
this.spring.register(BasicSecurityConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(post("/logout") |
||||
.with(csrf()) |
||||
.with(user("user")) |
||||
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)) |
||||
.andExpect(status().isNoContent()); |
||||
} |
||||
|
||||
// gh-4831
|
||||
@Test |
||||
public void logoutWhenAcceptAllThenReturnsStatusNoContent() throws Exception { |
||||
this.spring.register(BasicSecurityConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(post("/logout") |
||||
.with(csrf()) |
||||
.with(user("user")) |
||||
.header(HttpHeaders.ACCEPT, MediaType.ALL_VALUE)) |
||||
.andExpect(status().isNoContent()); |
||||
} |
||||
|
||||
// gh-3902
|
||||
@Test |
||||
public void logoutWhenAcceptFromChromeThenRedirectsToLogin() throws Exception { |
||||
this.spring.register(BasicSecurityConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(post("/logout") |
||||
.with(csrf()).with(user("user")) |
||||
.header(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")) |
||||
.andExpect(status().isFound()) |
||||
.andExpect(redirectedUrl("/login?logout")); |
||||
} |
||||
|
||||
// gh-3997
|
||||
@Test |
||||
public void logoutWhenXMLHttpRequestThenReturnsStatusNoContent() throws Exception { |
||||
this.spring.register(BasicSecurityConfig.class).autowire(); |
||||
|
||||
this.mvc.perform(post("/logout") |
||||
.with(csrf()) |
||||
.with(user("user")) |
||||
.header(HttpHeaders.ACCEPT, "text/html,application/json") |
||||
.header("X-Requested-With", "XMLHttpRequest")) |
||||
.andExpect(status().isNoContent()); |
||||
} |
||||
|
||||
@EnableWebSecurity |
||||
static class BasicSecurityConfig extends WebSecurityConfigurerAdapter { |
||||
} |
||||
} |
||||
Loading…
Reference in new issue