WebSecurityConfigurationTests groovy->java
Issue: gh-4939
This commit is contained in:
		
							parent
							
								
									b1f3d495d9
								
							
						
					
					
						commit
						c922fe3be1
					
				| 
						 | 
				
			
			@ -1,344 +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
 | 
			
		||||
 *
 | 
			
		||||
 *      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.annotation.web.configuration
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Modifier
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.*
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.factory.BeanCreationException
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired
 | 
			
		||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext
 | 
			
		||||
import org.springframework.context.annotation.Bean
 | 
			
		||||
import org.springframework.context.annotation.Configuration
 | 
			
		||||
import org.springframework.core.annotation.Order
 | 
			
		||||
import org.springframework.expression.ExpressionParser
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletRequest
 | 
			
		||||
import org.springframework.security.access.expression.SecurityExpressionHandler
 | 
			
		||||
import org.springframework.security.authentication.AuthenticationManager
 | 
			
		||||
import org.springframework.security.config.annotation.BaseSpringSpec
 | 
			
		||||
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.builders.WebSecurity
 | 
			
		||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurationTests.DuplicateOrderConfig;
 | 
			
		||||
import org.springframework.security.web.FilterChainProxy
 | 
			
		||||
import org.springframework.security.web.SecurityFilterChain
 | 
			
		||||
import org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator
 | 
			
		||||
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator
 | 
			
		||||
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler
 | 
			
		||||
import org.springframework.security.web.util.matcher.AnyRequestMatcher
 | 
			
		||||
import org.springframework.test.util.ReflectionTestUtils
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Rob Winch
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class WebSecurityConfigurationTests extends BaseSpringSpec {
 | 
			
		||||
 | 
			
		||||
	def "WebSecurityConfigurers are sorted"() {
 | 
			
		||||
		when:
 | 
			
		||||
			loadConfig(SortedWebSecurityConfigurerAdaptersConfig);
 | 
			
		||||
			List<SecurityFilterChain> filterChains = context.getBean(FilterChainProxy).filterChains
 | 
			
		||||
		then:
 | 
			
		||||
			filterChains[0].requestMatcher.pattern == "/ignore1"
 | 
			
		||||
			filterChains[0].filters.empty
 | 
			
		||||
			filterChains[1].requestMatcher.pattern == "/ignore2"
 | 
			
		||||
			filterChains[1].filters.empty
 | 
			
		||||
 | 
			
		||||
			filterChains[2].requestMatcher.pattern == "/role1/**"
 | 
			
		||||
			filterChains[3].requestMatcher.pattern == "/role2/**"
 | 
			
		||||
			filterChains[4].requestMatcher.pattern == "/role3/**"
 | 
			
		||||
			filterChains[5].requestMatcher.class == AnyRequestMatcher
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class SortedWebSecurityConfigurerAdaptersConfig {
 | 
			
		||||
		public AuthenticationManager authenticationManager() throws Exception {
 | 
			
		||||
			return new AuthenticationManagerBuilder()
 | 
			
		||||
				.inMemoryAuthentication()
 | 
			
		||||
					.withUser("marissa").password("koala").roles("USER").and()
 | 
			
		||||
					.withUser("paul").password("emu").roles("USER").and()
 | 
			
		||||
					.and()
 | 
			
		||||
				.build();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		@Order(1)
 | 
			
		||||
		public static class WebConfigurer1 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
			@Override
 | 
			
		||||
			public void configure(WebSecurity web)	throws Exception {
 | 
			
		||||
				web
 | 
			
		||||
					.ignoring()
 | 
			
		||||
						.antMatchers("/ignore1","/ignore2");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.antMatcher("/role1/**")
 | 
			
		||||
					.authorizeRequests()
 | 
			
		||||
						.anyRequest().hasRole("1");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		@Order(2)
 | 
			
		||||
		public static class WebConfigurer2 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.antMatcher("/role2/**")
 | 
			
		||||
						.authorizeRequests()
 | 
			
		||||
							.anyRequest().hasRole("2");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		@Order(3)
 | 
			
		||||
		public static class WebConfigurer3 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.antMatcher("/role3/**")
 | 
			
		||||
					.authorizeRequests()
 | 
			
		||||
						.anyRequest().hasRole("3");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		public static class WebConfigurer4 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.authorizeRequests()
 | 
			
		||||
						.anyRequest().hasRole("4");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	def "WebSecurityConfigurers fails with duplicate order"() {
 | 
			
		||||
		when:
 | 
			
		||||
			loadConfig(DuplicateOrderConfig);
 | 
			
		||||
		then:
 | 
			
		||||
			BeanCreationException e = thrown()
 | 
			
		||||
			e.message.contains "@Order on WebSecurityConfigurers must be unique"
 | 
			
		||||
			e.message.contains DuplicateOrderConfig.WebConfigurer1.class.name
 | 
			
		||||
			e.message.contains DuplicateOrderConfig.WebConfigurer2.class.name
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class DuplicateOrderConfig {
 | 
			
		||||
		public AuthenticationManager authenticationManager() throws Exception {
 | 
			
		||||
			return new AuthenticationManagerBuilder()
 | 
			
		||||
				.inMemoryAuthentication()
 | 
			
		||||
					.withUser("user").password("password").roles("USER").and()
 | 
			
		||||
					.and()
 | 
			
		||||
				.build();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		public static class WebConfigurer1 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.antMatcher("/role1/**")
 | 
			
		||||
					.authorizeRequests()
 | 
			
		||||
						.anyRequest().hasRole("1");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		public static class WebConfigurer2 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.antMatcher("/role2/**")
 | 
			
		||||
					.authorizeRequests()
 | 
			
		||||
						.anyRequest().hasRole("2");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	def "Override privilegeEvaluator"() {
 | 
			
		||||
		setup:
 | 
			
		||||
			WebInvocationPrivilegeEvaluator privilegeEvaluator = Mock()
 | 
			
		||||
			PrivilegeEvaluatorConfigurerAdapterConfig.PE = privilegeEvaluator
 | 
			
		||||
		when:
 | 
			
		||||
			loadConfig(PrivilegeEvaluatorConfigurerAdapterConfig)
 | 
			
		||||
		then:
 | 
			
		||||
			context.getBean(WebInvocationPrivilegeEvaluator) == privilegeEvaluator
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class PrivilegeEvaluatorConfigurerAdapterConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
		static WebInvocationPrivilegeEvaluator PE
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public void configure(WebSecurity web) throws Exception {
 | 
			
		||||
			web
 | 
			
		||||
				.privilegeEvaluator(PE)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	def "Override webSecurityExpressionHandler"() {
 | 
			
		||||
		setup:
 | 
			
		||||
			SecurityExpressionHandler expressionHandler = Mock()
 | 
			
		||||
			ExpressionParser parser = Mock()
 | 
			
		||||
			WebSecurityExpressionHandlerConfig.EH = expressionHandler
 | 
			
		||||
		when:
 | 
			
		||||
			loadConfig(WebSecurityExpressionHandlerConfig)
 | 
			
		||||
		then:
 | 
			
		||||
			context.getBean(SecurityExpressionHandler) == expressionHandler
 | 
			
		||||
			1 * expressionHandler.getExpressionParser() >> parser
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class WebSecurityExpressionHandlerConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
		static SecurityExpressionHandler EH
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public void configure(WebSecurity web) throws Exception {
 | 
			
		||||
			web
 | 
			
		||||
				.expressionHandler(EH)
 | 
			
		||||
		}
 | 
			
		||||
		@Override
 | 
			
		||||
		protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
			http
 | 
			
		||||
				.authorizeRequests()
 | 
			
		||||
					.expressionHandler(EH)
 | 
			
		||||
					.anyRequest().authenticated()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	def "#138 webSecurityExpressionHandler defaults"() {
 | 
			
		||||
		when:
 | 
			
		||||
			loadConfig(WebSecurityExpressionHandlerDefaultsConfig)
 | 
			
		||||
		then:
 | 
			
		||||
			SecurityExpressionHandler wseh = context.getBean(SecurityExpressionHandler)
 | 
			
		||||
			wseh instanceof DefaultWebSecurityExpressionHandler
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class WebSecurityExpressionHandlerDefaultsConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
			http
 | 
			
		||||
				.authorizeRequests()
 | 
			
		||||
					.anyRequest().authenticated()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	def "#138 WebInvocationPrivilegeEvaluator defaults"() {
 | 
			
		||||
		when:
 | 
			
		||||
			loadConfig(WebInvocationPrivilegeEvaluatorDefaultsConfig)
 | 
			
		||||
		then:
 | 
			
		||||
			WebInvocationPrivilegeEvaluator wipe = context.getBean(WebInvocationPrivilegeEvaluator)
 | 
			
		||||
			wipe instanceof DefaultWebInvocationPrivilegeEvaluator
 | 
			
		||||
			wipe.securityInterceptor != null
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class WebInvocationPrivilegeEvaluatorDefaultsConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
			http
 | 
			
		||||
				.authorizeRequests()
 | 
			
		||||
					.anyRequest().authenticated()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	def "SEC-2303: DefaultExpressionHandler has bean resolver set"() {
 | 
			
		||||
		when:
 | 
			
		||||
			loadConfig(DefaultExpressionHandlerSetsBeanResolverConfig)
 | 
			
		||||
		then: "the exposed bean has a BeanResolver set"
 | 
			
		||||
			ReflectionTestUtils.getField(context.getBean(SecurityExpressionHandler),"br")
 | 
			
		||||
		when:
 | 
			
		||||
			springSecurityFilterChain.doFilter(request, response, chain)
 | 
			
		||||
		then: "we can use the BeanResolver with a grant"
 | 
			
		||||
			noExceptionThrown()
 | 
			
		||||
		when: "we can use the Beanresolver with a deny"
 | 
			
		||||
			springSecurityFilterChain.doFilter(new MockHttpServletRequest(method:'POST'), response, chain)
 | 
			
		||||
		then:
 | 
			
		||||
			noExceptionThrown()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class DefaultExpressionHandlerSetsBeanResolverConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
			http
 | 
			
		||||
				.authorizeRequests()
 | 
			
		||||
					.anyRequest().access("request.method == 'GET' ? @b.grant() : @b.deny()")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Bean
 | 
			
		||||
		public MyBean b() {
 | 
			
		||||
			new MyBean()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static class MyBean {
 | 
			
		||||
			boolean deny() {
 | 
			
		||||
				false
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			boolean grant() {
 | 
			
		||||
				true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	def "SEC-2461: Multiple WebSecurityConfiguration instances cause null springSecurityFilterChain"() {
 | 
			
		||||
		setup:
 | 
			
		||||
			def parent = loadConfig(ParentConfig)
 | 
			
		||||
			def child = new AnnotationConfigApplicationContext()
 | 
			
		||||
			child.register(ChildConfig)
 | 
			
		||||
			child.parent = parent
 | 
			
		||||
		when:
 | 
			
		||||
			child.refresh()
 | 
			
		||||
		then: "springSecurityFilterChain can be found in parent and child"
 | 
			
		||||
			parent.getBean("springSecurityFilterChain")
 | 
			
		||||
			child.getBean("springSecurityFilterChain")
 | 
			
		||||
		and: "springSecurityFilterChain is defined in both parent and child (don't search parent)"
 | 
			
		||||
			parent.containsBeanDefinition("springSecurityFilterChain")
 | 
			
		||||
			child.containsBeanDefinition("springSecurityFilterChain")
 | 
			
		||||
		cleanup:
 | 
			
		||||
			child?.close()
 | 
			
		||||
			// parent.close() is in superclass
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class ParentConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
		@Autowired
 | 
			
		||||
		public void configureGlobal(AuthenticationManagerBuilder auth) {
 | 
			
		||||
			auth.inMemoryAuthentication()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class ChildConfig extends WebSecurityConfigurerAdapter { }
 | 
			
		||||
 | 
			
		||||
	def "SEC-2773: delegatingApplicationListener is static method"() {
 | 
			
		||||
		expect: 'delegatingApplicationListener to prevent premature instantiation of WebSecurityConfiguration'
 | 
			
		||||
		Modifier.isStatic(WebSecurityConfiguration.metaClass.methods.find { it.name == 'delegatingApplicationListener'}.modifiers)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,360 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.annotation.web.configuration;
 | 
			
		||||
 | 
			
		||||
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.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.context.annotation.Import;
 | 
			
		||||
import org.springframework.core.annotation.Order;
 | 
			
		||||
import org.springframework.expression.ExpressionParser;
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletRequest;
 | 
			
		||||
import org.springframework.security.access.expression.SecurityExpressionHandler;
 | 
			
		||||
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.builders.WebSecurity;
 | 
			
		||||
import org.springframework.security.config.test.SpringTestRule;
 | 
			
		||||
import org.springframework.security.config.users.AuthenticationTestConfiguration;
 | 
			
		||||
import org.springframework.security.web.FilterChainProxy;
 | 
			
		||||
import org.springframework.security.web.SecurityFilterChain;
 | 
			
		||||
import org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator;
 | 
			
		||||
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
 | 
			
		||||
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
 | 
			
		||||
import org.springframework.test.web.servlet.MockMvc;
 | 
			
		||||
import org.springframework.util.ClassUtils;
 | 
			
		||||
import org.springframework.web.bind.annotation.GetMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RestController;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.lang.reflect.Modifier;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.assertj.core.api.Assertions.catchThrowable;
 | 
			
		||||
import static org.mockito.Mockito.mock;
 | 
			
		||||
import static org.mockito.Mockito.when;
 | 
			
		||||
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.status;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests for {@link WebSecurityConfiguration}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rob Winch
 | 
			
		||||
 * @author Joe Grandja
 | 
			
		||||
 */
 | 
			
		||||
public class WebSecurityConfigurationTests {
 | 
			
		||||
	@Rule
 | 
			
		||||
	public final SpringTestRule spring = new SpringTestRule();
 | 
			
		||||
 | 
			
		||||
	@Autowired
 | 
			
		||||
	private MockMvc mockMvc;
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void loadConfigWhenWebSecurityConfigurersHaveOrderThenFilterChainsOrdered() throws Exception {
 | 
			
		||||
		this.spring.register(SortedWebSecurityConfigurerAdaptersConfig.class).autowire();
 | 
			
		||||
 | 
			
		||||
		FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
 | 
			
		||||
		List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
 | 
			
		||||
		assertThat(filterChains).hasSize(6);
 | 
			
		||||
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
 | 
			
		||||
 | 
			
		||||
		request.setServletPath("/ignore1");
 | 
			
		||||
		assertThat(filterChains.get(0).matches(request)).isTrue();
 | 
			
		||||
		assertThat(filterChains.get(0).getFilters()).isEmpty();
 | 
			
		||||
 | 
			
		||||
		request.setServletPath("/ignore2");
 | 
			
		||||
		assertThat(filterChains.get(1).matches(request)).isTrue();
 | 
			
		||||
		assertThat(filterChains.get(1).getFilters()).isEmpty();
 | 
			
		||||
 | 
			
		||||
		request.setServletPath("/role1/**");
 | 
			
		||||
		assertThat(filterChains.get(2).matches(request)).isTrue();
 | 
			
		||||
 | 
			
		||||
		request.setServletPath("/role2/**");
 | 
			
		||||
		assertThat(filterChains.get(3).matches(request)).isTrue();
 | 
			
		||||
 | 
			
		||||
		request.setServletPath("/role3/**");
 | 
			
		||||
		assertThat(filterChains.get(4).matches(request)).isTrue();
 | 
			
		||||
 | 
			
		||||
		request.setServletPath("/**");
 | 
			
		||||
		assertThat(filterChains.get(5).matches(request)).isTrue();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	@Import(AuthenticationTestConfiguration.class)
 | 
			
		||||
	static class SortedWebSecurityConfigurerAdaptersConfig {
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		@Order(1)
 | 
			
		||||
		static class WebConfigurer1 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
			@Override
 | 
			
		||||
			public void configure(WebSecurity web)	throws Exception {
 | 
			
		||||
				web
 | 
			
		||||
					.ignoring()
 | 
			
		||||
						.antMatchers("/ignore1", "/ignore2");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.antMatcher("/role1/**")
 | 
			
		||||
					.authorizeRequests()
 | 
			
		||||
						.anyRequest().hasRole("1");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		@Order(2)
 | 
			
		||||
		static class WebConfigurer2 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.antMatcher("/role2/**")
 | 
			
		||||
					.authorizeRequests()
 | 
			
		||||
						.anyRequest().hasRole("2");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		@Order(3)
 | 
			
		||||
		static class WebConfigurer3 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.antMatcher("/role3/**")
 | 
			
		||||
					.authorizeRequests()
 | 
			
		||||
						.anyRequest().hasRole("3");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		static class WebConfigurer4 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.authorizeRequests()
 | 
			
		||||
						.anyRequest().hasRole("4");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void loadConfigWhenWebSecurityConfigurersHaveSameOrderThenThrowBeanCreationException() throws Exception {
 | 
			
		||||
		Throwable thrown = catchThrowable(() -> this.spring.register(DuplicateOrderConfig.class).autowire());
 | 
			
		||||
 | 
			
		||||
		assertThat(thrown).isInstanceOf(BeanCreationException.class)
 | 
			
		||||
			.hasMessageContaining("@Order on WebSecurityConfigurers must be unique")
 | 
			
		||||
			.hasMessageContaining(DuplicateOrderConfig.WebConfigurer1.class.getName())
 | 
			
		||||
			.hasMessageContaining(DuplicateOrderConfig.WebConfigurer2.class.getName());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	@Import(AuthenticationTestConfiguration.class)
 | 
			
		||||
	static class DuplicateOrderConfig {
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		static class WebConfigurer1 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.antMatcher("/role1/**")
 | 
			
		||||
						.authorizeRequests()
 | 
			
		||||
							.anyRequest().hasRole("1");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Configuration
 | 
			
		||||
		static class WebConfigurer2 extends WebSecurityConfigurerAdapter {
 | 
			
		||||
			@Override
 | 
			
		||||
			protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
				http
 | 
			
		||||
					.antMatcher("/role2/**")
 | 
			
		||||
						.authorizeRequests()
 | 
			
		||||
							.anyRequest().hasRole("2");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void loadConfigWhenWebInvocationPrivilegeEvaluatorSetThenIsRegistered() throws Exception {
 | 
			
		||||
		PrivilegeEvaluatorConfigurerAdapterConfig.PRIVILEGE_EVALUATOR = mock(WebInvocationPrivilegeEvaluator.class);
 | 
			
		||||
 | 
			
		||||
		this.spring.register(PrivilegeEvaluatorConfigurerAdapterConfig.class).autowire();
 | 
			
		||||
 | 
			
		||||
		assertThat(this.spring.getContext().getBean(WebInvocationPrivilegeEvaluator.class))
 | 
			
		||||
			.isSameAs(PrivilegeEvaluatorConfigurerAdapterConfig.PRIVILEGE_EVALUATOR);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class PrivilegeEvaluatorConfigurerAdapterConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
		static WebInvocationPrivilegeEvaluator PRIVILEGE_EVALUATOR;
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public void configure(WebSecurity web) throws Exception {
 | 
			
		||||
			web.privilegeEvaluator(PRIVILEGE_EVALUATOR);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void loadConfigWhenSecurityExpressionHandlerSetThenIsRegistered() throws Exception {
 | 
			
		||||
		WebSecurityExpressionHandlerConfig.EXPRESSION_HANDLER = mock(SecurityExpressionHandler.class);
 | 
			
		||||
		when(WebSecurityExpressionHandlerConfig.EXPRESSION_HANDLER.getExpressionParser()).thenReturn(mock(ExpressionParser.class));
 | 
			
		||||
 | 
			
		||||
		this.spring.register(WebSecurityExpressionHandlerConfig.class).autowire();
 | 
			
		||||
 | 
			
		||||
		assertThat(this.spring.getContext().getBean(SecurityExpressionHandler.class))
 | 
			
		||||
			.isSameAs(WebSecurityExpressionHandlerConfig.EXPRESSION_HANDLER);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class WebSecurityExpressionHandlerConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
		static SecurityExpressionHandler EXPRESSION_HANDLER;
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public void configure(WebSecurity web) throws Exception {
 | 
			
		||||
			web.expressionHandler(EXPRESSION_HANDLER);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
			http
 | 
			
		||||
				.authorizeRequests()
 | 
			
		||||
					.anyRequest().authenticated()
 | 
			
		||||
					.expressionHandler(EXPRESSION_HANDLER);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void loadConfigWhenDefaultSecurityExpressionHandlerThenDefaultIsRegistered() throws Exception {
 | 
			
		||||
		this.spring.register(WebSecurityExpressionHandlerDefaultsConfig.class).autowire();
 | 
			
		||||
 | 
			
		||||
		assertThat(this.spring.getContext().getBean(SecurityExpressionHandler.class))
 | 
			
		||||
			.isInstanceOf(DefaultWebSecurityExpressionHandler.class);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class WebSecurityExpressionHandlerDefaultsConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
		@Override
 | 
			
		||||
		protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
			http
 | 
			
		||||
				.authorizeRequests()
 | 
			
		||||
					.anyRequest().authenticated();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void loadConfigWhenDefaultWebInvocationPrivilegeEvaluatorThenDefaultIsRegistered() throws Exception {
 | 
			
		||||
		this.spring.register(WebInvocationPrivilegeEvaluatorDefaultsConfig.class).autowire();
 | 
			
		||||
 | 
			
		||||
		assertThat(this.spring.getContext().getBean(WebInvocationPrivilegeEvaluator.class))
 | 
			
		||||
			.isInstanceOf(DefaultWebInvocationPrivilegeEvaluator.class);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class WebInvocationPrivilegeEvaluatorDefaultsConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
		@Override
 | 
			
		||||
		protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
			http
 | 
			
		||||
				.authorizeRequests()
 | 
			
		||||
					.anyRequest().authenticated();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// SEC-2303
 | 
			
		||||
	@Test
 | 
			
		||||
	public void loadConfigWhenDefaultSecurityExpressionHandlerThenBeanResolverSet() throws Exception {
 | 
			
		||||
		this.spring.register(DefaultExpressionHandlerSetsBeanResolverConfig.class).autowire();
 | 
			
		||||
 | 
			
		||||
		this.mockMvc.perform(get("/")).andExpect(status().isOk());
 | 
			
		||||
		this.mockMvc.perform(post("/")).andExpect(status().isForbidden());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class DefaultExpressionHandlerSetsBeanResolverConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
		@Override
 | 
			
		||||
		protected void configure(HttpSecurity http) throws Exception {
 | 
			
		||||
			http
 | 
			
		||||
				.authorizeRequests()
 | 
			
		||||
					.anyRequest().access("request.method == 'GET' ? @b.grant() : @b.deny()");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@RestController
 | 
			
		||||
		public class HomeController {
 | 
			
		||||
			@GetMapping("/")
 | 
			
		||||
			public String home() {
 | 
			
		||||
				return "home";
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Bean
 | 
			
		||||
		public MyBean b() {
 | 
			
		||||
			return new MyBean();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static class MyBean {
 | 
			
		||||
			public boolean deny() {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			public boolean grant() {
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Rule
 | 
			
		||||
	public SpringTestRule child = new SpringTestRule();
 | 
			
		||||
 | 
			
		||||
	// SEC-2461
 | 
			
		||||
	@Test
 | 
			
		||||
	public void loadConfigWhenMultipleWebSecurityConfigurationThenContextLoads() throws Exception {
 | 
			
		||||
		this.spring.register(ParentConfig.class).autowire();
 | 
			
		||||
 | 
			
		||||
		this.child.register(ChildConfig.class);
 | 
			
		||||
		this.child.getContext().setParent(this.spring.getContext());
 | 
			
		||||
		this.child.autowire();
 | 
			
		||||
 | 
			
		||||
		assertThat(this.spring.getContext().getBean("springSecurityFilterChain")).isNotNull();
 | 
			
		||||
		assertThat(this.child.getContext().getBean("springSecurityFilterChain")).isNotNull();
 | 
			
		||||
 | 
			
		||||
		assertThat(this.spring.getContext().containsBean("springSecurityFilterChain")).isTrue();
 | 
			
		||||
		assertThat(this.child.getContext().containsBean("springSecurityFilterChain")).isTrue();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class ParentConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
		@Autowired
 | 
			
		||||
		public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
 | 
			
		||||
			auth.inMemoryAuthentication();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableWebSecurity
 | 
			
		||||
	static class ChildConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// SEC-2773
 | 
			
		||||
	@Test
 | 
			
		||||
	public void getMethodDelegatingApplicationListenerWhenWebSecurityConfigurationThenIsStatic() throws Exception {
 | 
			
		||||
		Method method = ClassUtils.getMethod(WebSecurityConfiguration.class, "delegatingApplicationListener", null);
 | 
			
		||||
		assertThat(Modifier.isStatic(method.getModifiers())).isTrue();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue