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 f1a7b7e803..b7d088c570 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 @@ -22,6 +22,8 @@ import java.util.Map; import org.aopalliance.intercept.MethodInterceptor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + +import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AdviceMode; @@ -76,7 +78,8 @@ import org.springframework.util.Assert; * @see EnableGlobalMethodSecurity */ @Configuration -public class GlobalMethodSecurityConfiguration implements ImportAware { +public class GlobalMethodSecurityConfiguration + implements ImportAware, SmartInitializingSingleton { private static final Log logger = LogFactory .getLog(GlobalMethodSecurityConfiguration.class); private ObjectPostProcessor objectPostProcessor = new ObjectPostProcessor() { @@ -94,6 +97,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware { private ApplicationContext context; private MethodSecurityExpressionHandler expressionHandler; private Jsr250MethodSecurityMetadataSource jsr250MethodSecurityMetadataSource; + private MethodSecurityInterceptor methodSecurityInterceptor; /** * Creates the default MethodInterceptor which is a MethodSecurityInterceptor using @@ -117,18 +121,42 @@ public class GlobalMethodSecurityConfiguration implements ImportAware { */ @Bean public MethodInterceptor methodSecurityInterceptor() throws Exception { - MethodSecurityInterceptor methodSecurityInterceptor = isAspectJ() ? new AspectJMethodSecurityInterceptor() + this.methodSecurityInterceptor = isAspectJ() + ? new AspectJMethodSecurityInterceptor() : new MethodSecurityInterceptor(); methodSecurityInterceptor.setAccessDecisionManager(accessDecisionManager()); methodSecurityInterceptor.setAfterInvocationManager(afterInvocationManager()); - methodSecurityInterceptor.setAuthenticationManager(authenticationManager()); methodSecurityInterceptor .setSecurityMetadataSource(methodSecurityMetadataSource()); RunAsManager runAsManager = runAsManager(); if (runAsManager != null) { methodSecurityInterceptor.setRunAsManager(runAsManager); } - return methodSecurityInterceptor; + + return this.methodSecurityInterceptor; + } + + /* + * (non-Javadoc) + * + * @see org.springframework.beans.factory.SmartInitializingSingleton# + * afterSingletonsInstantiated() + */ + @Override + public void afterSingletonsInstantiated() { + try { + initializeMethodSecurityInterceptor(); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void initializeMethodSecurityInterceptor() throws Exception { + if(this.methodSecurityInterceptor == null) { + return; + } + this.methodSecurityInterceptor.setAuthenticationManager(authenticationManager()); } /** diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfigurationTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfigurationTests.groovy index 9f7401f357..bc9ee91152 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfigurationTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfigurationTests.groovy @@ -23,6 +23,7 @@ import org.springframework.context.annotation.Import import org.springframework.core.Ordered import org.springframework.core.annotation.Order import org.springframework.security.access.annotation.Secured +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.authentication.AuthenticationProvider import org.springframework.security.authentication.TestingAuthenticationToken @@ -485,4 +486,33 @@ class AuthenticationConfigurationTests extends BaseSpringSpec { UDS } } + + def 'EnableGlobalMethodSecurity configuration uses PreAuthorize does not cause BeanCurrentlyInCreationException'() { + when: + loadConfig(UsesPreAuthorizeMethodSecurityConfig,AuthenticationManagerBeanConfig) + then: + noExceptionThrown() + } + + @Configuration + @EnableGlobalMethodSecurity(prePostEnabled = true) + static class UsesPreAuthorizeMethodSecurityConfig { + @PreAuthorize("denyAll") + void run() {} + } + + + def 'EnableGlobalMethodSecurity uses method security service'() { + when: + loadConfig(ServicesConfig,UsesPreAuthorizeMethodSecurityConfig,AuthenticationManagerBeanConfig) + then: + noExceptionThrown() + } + + @Configuration + @EnableGlobalMethodSecurity(securedEnabled = true) + static class UsesServiceMethodSecurityConfig { + @Autowired + Service service + } } \ No newline at end of file