浏览代码

SEC-2815: Delay looking up AuthenticationConfiguration

Rob Winch 10 年之前
父节点
当前提交
62649af0aa

+ 6 - 6
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() {

+ 65 - 0
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<String,Object> beforeInit = new HashMap<String,Object>()
+        Map<String,Object> afterInit = new HashMap<String,Object>()
+
+        @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
+        }
+    }
 }