From 62649af0aa07b9681e4679a2fa56112a7e3b98cf Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Mon, 19 Jan 2015 16:38:30 -0600 Subject: [PATCH] SEC-2815: Delay looking up AuthenticationConfiguration --- .../GlobalMethodSecurityConfiguration.java | 12 ++-- ...balMethodSecurityConfigurationTests.groovy | 65 +++++++++++++++++++ 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.java b/config/src/main/java/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.java index d48455eadc..855fef62cd 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.java +++ b/config/src/main/java/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.java @@ -24,6 +24,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.*; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.annotation.AnnotationUtils; @@ -85,8 +86,8 @@ public class GlobalMethodSecurityConfiguration implements ImportAware { private AuthenticationManagerBuilder auth; private boolean disableAuthenticationRegistry; private AnnotationAttributes enableMethodSecurity; + private ApplicationContext context; private MethodSecurityExpressionHandler expressionHandler; - private AuthenticationConfiguration authenticationConfiguration; /** * Creates the default MethodInterceptor which is a MethodSecurityInterceptor using the following methods to @@ -351,14 +352,13 @@ public class GlobalMethodSecurityConfiguration implements ImportAware { this.defaultMethodExpressionHandler.setPermissionEvaluator(permissionEvaluators.get(0)); } - @Autowired(required = false) - public void setAuthenticationConfiguration(AuthenticationConfiguration authenticationConfiguration) { - this.authenticationConfiguration = authenticationConfiguration; + @Autowired + public void setApplicationContext(ApplicationContext context) { + this.context = context; } private AuthenticationConfiguration getAuthenticationConfiguration() { - Assert.notNull(authenticationConfiguration, "authenticationConfiguration cannot be null"); - return authenticationConfiguration; + return context.getBean(AuthenticationConfiguration.class); } private boolean prePostEnabled() { diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfigurationTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfigurationTests.groovy index 761250cf8b..4b77105051 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfigurationTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfigurationTests.groovy @@ -15,6 +15,12 @@ */ package org.springframework.security.config.annotation.method.configuration +import org.springframework.beans.BeansException +import org.springframework.beans.factory.config.BeanPostProcessor +import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter + +import javax.sql.DataSource + import static org.fest.assertions.Assertions.assertThat import static org.junit.Assert.fail @@ -331,4 +337,63 @@ public class GlobalMethodSecurityConfigurationTests extends BaseSpringSpec { new MethodSecurityServiceImpl() } } + + def "SEC-2815: @EnableGlobalMethodSecurity does not trigger eager initialization of Beans in GlobalAuthenticationConfigurer"() { + setup: + Sec2815Config.dataSource = Mock(DataSource) + when: 'load a Configuration that uses a Bean (DataSource) in a GlobalAuthenticationConfigurerAdapter' + loadConfig(Sec2815Config) + then: 'The Bean (DataSource) is still properly post processed with all BeanPostProcessor' + context.getBean(MockBeanPostProcessor).beforeInit['dataSource'] + context.getBean(MockBeanPostProcessor).afterInit['dataSource'] + } + + @EnableGlobalMethodSecurity(prePostEnabled = true) + static class Sec2815Config { + static DataSource dataSource; + + @Bean + public MethodSecurityService service() { + new MethodSecurityServiceImpl() + } + + @Bean + public MockBeanPostProcessor mockBeanPostProcessor() { + new MockBeanPostProcessor() + } + + @Bean + public DataSource dataSource() { + dataSource + } + + @Configuration + static class AuthConfig extends GlobalAuthenticationConfigurerAdapter { + @Autowired + DataSource dataSource + + @Override + void init(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + } + } + } + + + static class MockBeanPostProcessor implements BeanPostProcessor { + Map beforeInit = new HashMap() + Map afterInit = new HashMap() + + @Override + Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + beforeInit[beanName] = bean + bean + } + + @Override + Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + afterInit[beanName] = bean + bean + } + } }