diff --git a/config/src/test/groovy/org/springframework/security/config/http/MultiHttpBlockConfigTests.groovy b/config/src/test/groovy/org/springframework/security/config/http/MultiHttpBlockConfigTests.groovy deleted file mode 100644 index 6d54e6b384..0000000000 --- a/config/src/test/groovy/org/springframework/security/config/http/MultiHttpBlockConfigTests.groovy +++ /dev/null @@ -1,133 +0,0 @@ -package org.springframework.security.config.http - -import static org.mockito.Mockito.* - -import org.powermock.api.mockito.internal.verification.VerifyNoMoreInteractions; -import org.springframework.beans.factory.parsing.BeanDefinitionParsingException -import org.springframework.mock.web.MockFilterChain; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.TestingAuthenticationToken; -import org.springframework.security.config.BeanIds -import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.web.FilterChainProxy -import org.junit.Assert -import org.springframework.beans.factory.BeanCreationException -import org.springframework.security.web.SecurityFilterChain - -/** - * Tests scenarios with multiple <http> elements. - * - * @author Luke Taylor - */ -class MultiHttpBlockConfigTests extends AbstractHttpConfigTests { - - def multipleHttpElementsAreSupported () { - when: "Two elements are used" - xml.http(pattern: '/stateless/**', 'create-session': 'stateless') { - 'http-basic'() - } - xml.http(pattern: '/stateful/**') { - 'form-login'() - } - createAppContext() - FilterChainProxy fcp = appContext.getBean(BeanIds.FILTER_CHAIN_PROXY) - def filterChains = fcp.getFilterChains(); - - then: - filterChains.size() == 2 - filterChains[0].requestMatcher.pattern == '/stateless/**' - } - - def duplicateHttpElementsAreRejected () { - when: "Two elements are used" - xml.http('create-session': 'stateless') { - 'http-basic'() - } - xml.http() { - 'form-login'() - } - createAppContext() - then: - BeanCreationException e = thrown() - e.cause instanceof IllegalArgumentException - } - - def duplicatePatternsAreRejected () { - when: "Two elements with the same pattern are used" - xml.http(pattern: '/stateless/**', 'create-session': 'stateless') { - 'http-basic'() - } - xml.http(pattern: '/stateless/**') { - 'form-login'() - } - createAppContext() - then: - BeanCreationException e = thrown() - e.cause instanceof IllegalArgumentException - } - - - def 'SEC-1937: http@authentication-manager-ref and multi authentication-mananager'() { - setup: - xml.http('authentication-manager-ref' : 'authManager', 'pattern' : '/first/**') { - 'form-login'('login-processing-url': '/first/login') - csrf(disabled:true) - } - xml.http('authentication-manager-ref' : 'authManager2') { - 'form-login'() - csrf(disabled:true) - } - mockBean(UserDetailsService,'uds') - mockBean(UserDetailsService,'uds2') - createAppContext(""" - - - - - - -""") - UserDetailsService uds = appContext.getBean('uds') - UserDetailsService uds2 = appContext.getBean('uds2') - when: - MockHttpServletRequest request = new MockHttpServletRequest("GET", "") - MockHttpServletResponse response = new MockHttpServletResponse() - MockFilterChain chain = new MockFilterChain() - request.servletPath = "/first/login" - request.requestURI = "/first/login" - request.method = 'POST' - springSecurityFilterChain.doFilter(request,response,chain) - then: - verify(uds).loadUserByUsername(anyString()) || true - verifyZeroInteractions(uds2) || true - when: - MockHttpServletRequest request2 = new MockHttpServletRequest("GET", "") - MockHttpServletResponse response2 = new MockHttpServletResponse() - MockFilterChain chain2 = new MockFilterChain() - request2.servletPath = "/login" - request2.requestURI = "/login" - request2.method = 'POST' - springSecurityFilterChain.doFilter(request2,response2,chain2) - then: - verify(uds2).loadUserByUsername(anyString()) || true - verifyNoMoreInteractions(uds) || true - } - - def multipleAuthenticationManagersWorks () { - xml.http(name: 'basic', pattern: '/basic/**', ) { - 'http-basic'() - } - xml.http(pattern: '/form/**') { - 'form-login'() - } - createAppContext() - FilterChainProxy fcp = appContext.getBean(BeanIds.FILTER_CHAIN_PROXY) - SecurityFilterChain basicChain = fcp.filterChains[0]; - - expect: - Assert.assertSame (basicChain, appContext.getBean('basic')) - } -} diff --git a/config/src/test/java/org/springframework/security/config/http/MultiHttpBlockConfigTests.java b/config/src/test/java/org/springframework/security/config/http/MultiHttpBlockConfigTests.java new file mode 100644 index 0000000000..5704431f15 --- /dev/null +++ b/config/src/test/java/org/springframework/security/config/http/MultiHttpBlockConfigTests.java @@ -0,0 +1,116 @@ +/* + * 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.junit.Rule; +import org.junit.Test; + +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.config.test.SpringTestRule; +import org.springframework.stereotype.Controller; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.web.bind.annotation.GetMapping; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +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.result.MockMvcResultMatchers.redirectedUrl; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Tests scenarios with multiple <http> elements. + * + * @author Luke Taylor + */ +public class MultiHttpBlockConfigTests { + private static final String CONFIG_LOCATION_PREFIX = + "classpath:org/springframework/security/config/http/MultiHttpBlockConfigTests"; + + @Autowired + MockMvc mvc; + + @Rule + public final SpringTestRule spring = new SpringTestRule(); + + @Test + public void requestWhenUsingMutuallyExclusiveHttpElementsThenIsRoutedAccordingly() + throws Exception { + + this.spring.configLocations(this.xml("DistinctHttpElements")).autowire(); + + this.mvc.perform(MockMvcRequestBuilders.get("/first") + .with(httpBasic("user", "password"))) + .andExpect(status().isOk()); + + this.mvc.perform(post("/second/login") + .param("username", "user") + .param("password", "password") + .with(csrf())) + .andExpect(status().isFound()) + .andExpect(redirectedUrl("/")); + } + + @Test + public void configureWhenUsingDuplicateHttpElementsThenThrowsWiringException() { + assertThatCode(() -> this.spring.configLocations(this.xml("IdenticalHttpElements")).autowire()) + .isInstanceOf(BeanCreationException.class) + .hasCauseInstanceOf(IllegalArgumentException.class); + } + + @Test + public void configureWhenUsingIndenticallyPatternedHttpElementsThenThrowsWiringException() { + assertThatCode(() -> this.spring.configLocations(this.xml("IdenticallyPatternedHttpElements")).autowire()) + .isInstanceOf(BeanCreationException.class) + .hasCauseInstanceOf(IllegalArgumentException.class); + } + + /** + * SEC-1937 + */ + @Test + public void requestWhenTargettingAuthenticationManagersToCorrespondingHttpElementsThenAuthenticationProceeds() + throws Exception { + + this.spring.configLocations(this.xml("Sec1937")).autowire(); + + this.mvc.perform(get("/first") + .with(httpBasic("first", "password")) + .with(csrf())) + .andExpect(status().isOk()); + + this.mvc.perform(post("/second/login") + .param("username", "second") + .param("password", "password") + .with(csrf())) + .andExpect(redirectedUrl("/")); + } + + @Controller + static class BasicController { + @GetMapping("/first") + public String first() { + return "ok"; + } + } + + private String xml(String configName) { + return CONFIG_LOCATION_PREFIX + "-" + configName + ".xml"; + } +} diff --git a/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-DistinctHttpElements.xml b/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-DistinctHttpElements.xml new file mode 100644 index 0000000000..be89f7d977 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-DistinctHttpElements.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-IdenticalHttpElements.xml b/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-IdenticalHttpElements.xml new file mode 100644 index 0000000000..ba1c05489c --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-IdenticalHttpElements.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-IdenticallyPatternedHttpElements.xml b/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-IdenticallyPatternedHttpElements.xml new file mode 100644 index 0000000000..e027a52dff --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-IdenticallyPatternedHttpElements.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-Sec1937.xml b/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-Sec1937.xml new file mode 100644 index 0000000000..fbe6d7d572 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-Sec1937.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +