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