SEC-2461: Multi WebSecurityConfiguration does not create null springSecurityFilterChain
This commit is contained in:
parent
ec8b48150d
commit
6b42a2eae1
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.security.config.annotation.SecurityConfigurer;
|
||||
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* A class used to get all the {@link WebSecurityConfigurer} instances from the
|
||||
* current {@link ApplicationContext} but ignoring the parent.
|
||||
*
|
||||
* @author Rob Winch
|
||||
*
|
||||
*/
|
||||
final class AutowiredWebSecurityConfigurersIgnoreParents {
|
||||
|
||||
private final ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
public AutowiredWebSecurityConfigurersIgnoreParents(ConfigurableListableBeanFactory beanFactory) {
|
||||
Assert.notNull(beanFactory,"beanFactory cannot be null");
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public List<SecurityConfigurer<Filter, WebSecurity>> getWebSecurityConfigurers() {
|
||||
List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers = new ArrayList<SecurityConfigurer<Filter, WebSecurity>>();
|
||||
Map<String, WebSecurityConfigurer> beansOfType = beanFactory.getBeansOfType(WebSecurityConfigurer.class);
|
||||
for(Entry<String,WebSecurityConfigurer> entry : beansOfType.entrySet()) {
|
||||
webSecurityConfigurers.add(entry.getValue());
|
||||
}
|
||||
return webSecurityConfigurers;
|
||||
}
|
||||
}
|
|
@ -23,6 +23,8 @@ import javax.servlet.Filter;
|
|||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
|
@ -34,7 +36,6 @@ import org.springframework.core.annotation.AnnotationUtils;
|
|||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.security.access.expression.SecurityExpressionHandler;
|
||||
import org.springframework.security.config.annotation.AlreadyBuiltException;
|
||||
import org.springframework.security.config.annotation.ObjectPostProcessor;
|
||||
import org.springframework.security.config.annotation.SecurityConfigurer;
|
||||
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
|
||||
|
@ -88,11 +89,7 @@ public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAwa
|
|||
if(!hasConfigurers) {
|
||||
throw new IllegalStateException("At least one non-null instance of "+ WebSecurityConfigurer.class.getSimpleName()+" must be exposed as a @Bean when using @EnableWebSecurity. Hint try extending "+ WebSecurityConfigurerAdapter.class.getSimpleName());
|
||||
}
|
||||
try {
|
||||
return webSecurity.build();
|
||||
} catch (AlreadyBuiltException e) {
|
||||
return webSecurity.getObject();
|
||||
}
|
||||
return webSecurity.build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,7 +112,7 @@ public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAwa
|
|||
*/
|
||||
@Autowired(required = false)
|
||||
public void setFilterChainProxySecurityConfigurer(ObjectPostProcessor<Object> objectPostProcessor,
|
||||
List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers) throws Exception {
|
||||
@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers) throws Exception {
|
||||
webSecurity = objectPostProcessor.postProcess(new WebSecurity(objectPostProcessor));
|
||||
if(debugEnabled != null) {
|
||||
webSecurity.debug(debugEnabled);
|
||||
|
@ -137,6 +134,10 @@ public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAwa
|
|||
this.webSecurityConfigurers = webSecurityConfigurers;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AutowiredWebSecurityConfigurersIgnoreParents autowiredWebSecurityConfigurersIgnoreParents(ConfigurableListableBeanFactory beanFactory) {
|
||||
return new AutowiredWebSecurityConfigurersIgnoreParents(beanFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom verision of the Spring provided AnnotationAwareOrderComparator
|
||||
|
|
|
@ -17,31 +17,28 @@ package org.springframework.security.config.annotation.web.configuration;
|
|||
|
||||
import static org.junit.Assert.*
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
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.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.authentication.event.AuthenticationSuccessEvent;
|
||||
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.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.access.expression.WebSecurityExpressionHandler;
|
||||
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
|
||||
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.access.expression.WebSecurityExpressionHandler
|
||||
import org.springframework.security.web.util.matcher.AnyRequestMatcher
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.test.util.ReflectionTestUtils
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
|
@ -313,4 +310,36 @@ class WebSecurityConfigurationTests extends BaseSpringSpec {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@Configuration
|
||||
static class ParentConfig extends WebSecurityConfigurerAdapter {
|
||||
@Autowired
|
||||
public void configureGlobal(AuthenticationManagerBuilder auth) {
|
||||
auth.inMemoryAuthentication()
|
||||
}
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
@Configuration
|
||||
static class ChildConfig extends WebSecurityConfigurerAdapter { }
|
||||
}
|
||||
|
|
|
@ -17,9 +17,10 @@ package org.springframework.security.config.annotation.web.configuration.sec2377
|
|||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
@EnableWebSecurity
|
||||
@Configuration
|
||||
public class Sec2377BConfig {
|
||||
public class Sec2377BConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue