diff --git a/config/src/test/groovy/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests.groovy b/config/src/test/groovy/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests.groovy
deleted file mode 100644
index de68710f25..0000000000
--- a/config/src/test/groovy/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests.groovy
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright 2002-2012 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
- *
- * http://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.http
-
-import static org.springframework.security.config.ConfigTestUtils.AUTH_PROVIDER_XML
-
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-import org.springframework.mock.web.MockFilterChain
-import org.springframework.mock.web.MockHttpServletRequest
-import org.springframework.mock.web.MockHttpServletResponse
-import org.springframework.security.authentication.TestingAuthenticationToken
-import org.springframework.security.core.context.SecurityContext
-import org.springframework.security.core.context.SecurityContextHolder
-import org.springframework.security.web.access.ExceptionTranslationFilter
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
-import org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler
-import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler
-import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint
-import org.springframework.security.web.authentication.www.BasicAuthenticationFilter
-import org.springframework.security.web.context.HttpSessionSecurityContextRepository
-import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter
-
-/**
- *
- * @author Rob Winch
- */
-class SecurityContextHolderAwareRequestConfigTests extends AbstractHttpConfigTests {
-
- def withAutoConfig() {
- httpAutoConfig () {
- csrf(disabled:true)
- }
- createAppContext(AUTH_PROVIDER_XML)
-
- def securityContextAwareFilter = getFilter(SecurityContextHolderAwareRequestFilter)
-
- expect:
- securityContextAwareFilter.authenticationEntryPoint.loginFormUrl == getFilter(ExceptionTranslationFilter).authenticationEntryPoint.loginFormUrl
- securityContextAwareFilter.authenticationManager == getFilter(UsernamePasswordAuthenticationFilter).authenticationManager
- securityContextAwareFilter.logoutHandlers.size() == 1
- securityContextAwareFilter.logoutHandlers[0].class == SecurityContextLogoutHandler
- }
-
- def explicitEntryPoint() {
- xml.http() {
- 'http-basic'('entry-point-ref': 'ep')
- }
- bean('ep', BasicAuthenticationEntryPoint.class.name, ['realmName':'whocares'],[:])
- createAppContext(AUTH_PROVIDER_XML)
-
- def securityContextAwareFilter = getFilter(SecurityContextHolderAwareRequestFilter)
-
- expect:
- securityContextAwareFilter.authenticationEntryPoint == getFilter(ExceptionTranslationFilter).authenticationEntryPoint
- securityContextAwareFilter.authenticationManager == getFilter(BasicAuthenticationFilter).authenticationManager
- securityContextAwareFilter.logoutHandlers == null
- }
-
- def formLogin() {
- xml.http() {
- 'form-login'()
- }
- createAppContext(AUTH_PROVIDER_XML)
-
- def securityContextAwareFilter = getFilter(SecurityContextHolderAwareRequestFilter)
-
- expect:
- securityContextAwareFilter.authenticationEntryPoint.loginFormUrl == getFilter(ExceptionTranslationFilter).authenticationEntryPoint.loginFormUrl
- securityContextAwareFilter.authenticationManager == getFilter(UsernamePasswordAuthenticationFilter).authenticationManager
- securityContextAwareFilter.logoutHandlers == null
- }
-
- def multiHttp() {
- xml.http('authentication-manager-ref' : 'authManager', 'pattern' : '/first/**') {
- 'form-login'('login-page' : '/login')
- 'logout'('invalidate-session' : 'true')
- csrf(disabled:true)
- }
- xml.http('authentication-manager-ref' : 'authManager2') {
- 'form-login'('login-page' : '/login2')
- 'logout'('invalidate-session' : 'false')
- csrf(disabled:true)
- }
-
- String secondAuthManager = AUTH_PROVIDER_XML.replace("alias='authManager'", "id='authManager2'")
- createAppContext(AUTH_PROVIDER_XML + secondAuthManager)
-
- def securityContextAwareFilter = getFilters('/first/filters').find { it instanceof SecurityContextHolderAwareRequestFilter }
- def secondSecurityContextAwareFilter = getFilter(SecurityContextHolderAwareRequestFilter)
-
- expect:
- securityContextAwareFilter.authenticationEntryPoint.loginFormUrl == '/login'
- securityContextAwareFilter.authenticationManager == getFilters('/first/filters').find { it instanceof UsernamePasswordAuthenticationFilter}.authenticationManager
- securityContextAwareFilter.authenticationManager.parent == appContext.getBean('authManager')
- securityContextAwareFilter.logoutHandlers.size() == 1
- securityContextAwareFilter.logoutHandlers[0].class == SecurityContextLogoutHandler
- securityContextAwareFilter.logoutHandlers[0].invalidateHttpSession == true
-
- secondSecurityContextAwareFilter.authenticationEntryPoint.loginFormUrl == '/login2'
- secondSecurityContextAwareFilter.authenticationManager == getFilter(UsernamePasswordAuthenticationFilter).authenticationManager
- secondSecurityContextAwareFilter.authenticationManager.parent == appContext.getBean('authManager2')
- securityContextAwareFilter.logoutHandlers.size() == 1
- secondSecurityContextAwareFilter.logoutHandlers[0].class == SecurityContextLogoutHandler
- secondSecurityContextAwareFilter.logoutHandlers[0].invalidateHttpSession == false
- }
-
- def logoutCustom() {
- xml.http() {
- 'form-login'('login-page' : '/login')
- 'logout'('invalidate-session' : 'false', 'logout-success-url' : '/login?logout', 'delete-cookies' : 'JSESSIONID')
- csrf(disabled:true)
- }
- createAppContext(AUTH_PROVIDER_XML)
-
- def securityContextAwareFilter = getFilter(SecurityContextHolderAwareRequestFilter)
-
- expect:
- securityContextAwareFilter.authenticationEntryPoint.loginFormUrl == getFilter(ExceptionTranslationFilter).authenticationEntryPoint.loginFormUrl
- securityContextAwareFilter.authenticationManager == getFilter(UsernamePasswordAuthenticationFilter).authenticationManager
- securityContextAwareFilter.logoutHandlers.size() == 2
- securityContextAwareFilter.logoutHandlers[0].class == SecurityContextLogoutHandler
- securityContextAwareFilter.logoutHandlers[0].invalidateHttpSession == false
- securityContextAwareFilter.logoutHandlers[1].class == CookieClearingLogoutHandler
- securityContextAwareFilter.logoutHandlers[1].cookiesToClear == ['JSESSIONID']
- }
-
- def 'SEC-2926: Role Prefix is set'() {
- setup:
- httpAutoConfig () {
-
- }
- createAppContext(AUTH_PROVIDER_XML)
-
- MockFilterChain chain = new MockFilterChain() {
- public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
- assert request.isUserInRole("USER")
-
- super.doFilter(request,response)
- }
- }
- MockHttpServletRequest request = new MockHttpServletRequest(method:'GET')
- SecurityContext context = SecurityContextHolder.createEmptyContext()
- context.setAuthentication(new TestingAuthenticationToken("user", "pass", "ROLE_USER"))
- request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context)
-
- when:
- springSecurityFilterChain.doFilter(request, new MockHttpServletResponse(), chain)
- then:
- chain.request != null
- }
-}
diff --git a/config/src/test/java/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests.java b/config/src/test/java/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests.java
new file mode 100644
index 0000000000..af22e07fc4
--- /dev/null
+++ b/config/src/test/java/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2002-2018 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
+ *
+ * http://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.http;
+
+import org.apache.http.HttpHeaders;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mock.web.MockHttpSession;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+/**
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@SecurityTestExecutionListeners
+public class SecurityContextHolderAwareRequestConfigTests {
+
+ private static final String CONFIG_LOCATION_PREFIX =
+ "classpath:org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests";
+
+ @Rule
+ public final SpringTestRule spring = new SpringTestRule();
+
+ @Autowired
+ private MockMvc mvc;
+
+ @Test
+ public void servletLoginWhenUsingDefaultConfigurationThenUsesSpringSecurity()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("Simple")).autowire();
+
+ this.mvc.perform(get("/good-login"))
+ .andExpect(status().isOk())
+ .andExpect(content().string("user"));
+ }
+
+ @Test
+ public void servletAuthenticateWhenUsingDefaultConfigurationThenUsesSpringSecurity()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("Simple")).autowire();
+
+ this.mvc.perform(get("/authenticate"))
+ .andExpect(status().isFound())
+ .andExpect(redirectedUrl("http://localhost/login"));
+ }
+
+ @Test
+ public void servletLogoutWhenUsingDefaultConfigurationThenUsesSpringSecurity()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("Simple")).autowire();
+
+ MvcResult result = this.mvc.perform(get("/good-login")).andReturn();
+
+ MockHttpSession session = (MockHttpSession) result.getRequest().getSession(false);
+
+ assertThat(session).isNotNull();
+
+ result = this.mvc.perform(get("/do-logout").session(session))
+ .andExpect(status().isOk())
+ .andExpect(content().string(""))
+ .andReturn();
+
+ session = (MockHttpSession) result.getRequest().getSession(false);
+
+ assertThat(session).isNull();
+ }
+
+ @Test
+ public void servletAuthenticateWhenUsingHttpBasicThenUsesSpringSecurity()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("HttpBasic")).autowire();
+
+ this.mvc.perform(get("/authenticate"))
+ .andExpect(status().isUnauthorized())
+ .andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, containsString("discworld")));
+ }
+
+ @Test
+ public void servletAuthenticateWhenUsingFormLoginThenUsesSpringSecurity()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("FormLogin")).autowire();
+
+ this.mvc.perform(get("/authenticate"))
+ .andExpect(status().isFound())
+ .andExpect(redirectedUrl("http://localhost/login"));
+ }
+
+ @Test
+ public void servletLoginWhenUsingMultipleHttpConfigsThenUsesSpringSecurity()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("MultiHttp")).autowire();
+
+ this.mvc.perform(get("/good-login"))
+ .andExpect(status().isOk())
+ .andExpect(content().string("user"));
+
+ this.mvc.perform(get("/v2/good-login"))
+ .andExpect(status().isOk())
+ .andExpect(content().string("user2"));
+ }
+
+ @Test
+ public void servletAuthenticateWhenUsingMultipleHttpConfigsThenUsesSpringSecurity()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("MultiHttp")).autowire();
+
+ this.mvc.perform(get("/authenticate"))
+ .andExpect(status().isFound())
+ .andExpect(redirectedUrl("http://localhost/login"));
+
+ this.mvc.perform(get("/v2/authenticate"))
+ .andExpect(status().isFound())
+ .andExpect(redirectedUrl("http://localhost/login2"));
+
+ }
+
+ @Test
+ public void servletLogoutWhenUsingMultipleHttpConfigsThenUsesSpringSecurity()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("MultiHttp")).autowire();
+
+ MvcResult result = this.mvc.perform(get("/good-login")).andReturn();
+
+ MockHttpSession session = (MockHttpSession) result.getRequest().getSession(false);
+
+ assertThat(session).isNotNull();
+
+ result = this.mvc.perform(get("/do-logout").session(session))
+ .andExpect(status().isOk())
+ .andExpect(content().string(""))
+ .andReturn();
+
+ session = (MockHttpSession) result.getRequest().getSession(false);
+
+ assertThat(session).isNotNull();
+
+ result = this.mvc.perform(get("/v2/good-login")).andReturn();
+
+ session = (MockHttpSession) result.getRequest().getSession(false);
+
+ assertThat(session).isNotNull();
+
+ result = this.mvc.perform(get("/v2/do-logout").session(session))
+ .andExpect(status().isOk())
+ .andExpect(content().string(""))
+ .andReturn();
+
+ session = (MockHttpSession) result.getRequest().getSession(false);
+
+ assertThat(session).isNull();
+ }
+
+ @Test
+ public void servletLogoutWhenUsingCustomLogoutThenUsesSpringSecurity()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("Logout")).autowire();
+
+ this.mvc.perform(get("/authenticate"))
+ .andExpect(status().isFound())
+ .andExpect(redirectedUrl("http://localhost/signin"));
+
+ MvcResult result = this.mvc.perform(get("/good-login")).andReturn();
+
+ MockHttpSession session = (MockHttpSession) result.getRequest().getSession(false);
+
+ assertThat(session).isNotNull();
+
+ result = this.mvc.perform(get("/do-logout").session(session))
+ .andExpect(status().isOk())
+ .andExpect(content().string(""))
+ .andExpect(cookie().maxAge("JSESSIONID", 0))
+ .andReturn();
+
+ session = (MockHttpSession) result.getRequest().getSession(false);
+
+ assertThat(session).isNotNull();
+ }
+
+ /**
+ * SEC-2926: Role Prefix is set
+ */
+ @Test
+ @WithMockUser
+ public void servletIsUserInRoleWhenUsingDefaultConfigThenRoleIsSet()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("Simple")).autowire();
+
+ this.mvc.perform(get("/role")).andExpect(content().string("true"));
+ }
+
+ @RestController
+ public static class ServletAuthenticatedController {
+ @GetMapping("/v2/good-login")
+ public String v2Login(HttpServletRequest request) throws ServletException {
+
+ request.login("user2", "password2");
+
+ return this.principal();
+ }
+
+ @GetMapping("/good-login")
+ public String login(HttpServletRequest request) throws ServletException {
+
+ request.login("user", "password");
+
+ return this.principal();
+ }
+
+ @GetMapping("/v2/authenticate")
+ public String v2Authenticate(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+
+ return this.authenticate(request, response);
+ }
+
+ @GetMapping("/authenticate")
+ public String authenticate(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+
+ request.authenticate(response);
+
+ return this.principal();
+ }
+
+ @GetMapping("/v2/do-logout")
+ public String v2Logout(HttpServletRequest request) throws ServletException {
+ return this.logout(request);
+ }
+
+ @GetMapping("/do-logout")
+ public String logout(HttpServletRequest request) throws ServletException {
+ request.logout();
+
+ return this.principal();
+ }
+
+ @GetMapping("/role")
+ public String role(HttpServletRequest request) {
+ return String.valueOf(request.isUserInRole("USER"));
+ }
+
+ private String principal() {
+ if ( SecurityContextHolder.getContext().getAuthentication() != null ) {
+ return SecurityContextHolder.getContext().getAuthentication().getName();
+ }
+ return null;
+ }
+ }
+
+ private String xml(String configName) {
+ return CONFIG_LOCATION_PREFIX + "-" + configName + ".xml";
+ }
+}
diff --git a/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-FormLogin.xml b/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-FormLogin.xml
new file mode 100644
index 0000000000..0caf67fac9
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-FormLogin.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-HttpBasic.xml b/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-HttpBasic.xml
new file mode 100644
index 0000000000..b89d96a67a
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-HttpBasic.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-Logout.xml b/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-Logout.xml
new file mode 100644
index 0000000000..d2b0532fe1
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-Logout.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-MultiHttp.xml b/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-MultiHttp.xml
new file mode 100644
index 0000000000..38d74133a7
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-MultiHttp.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-Simple.xml b/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-Simple.xml
new file mode 100644
index 0000000000..8d8e2473b1
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/SecurityContextHolderAwareRequestConfigTests-Simple.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+