diff --git a/core/src/main/java/org/springframework/security/config/ConfigUtils.java b/core/src/main/java/org/springframework/security/config/ConfigUtils.java
new file mode 100644
index 0000000000..67d8ee1fe1
--- /dev/null
+++ b/core/src/main/java/org/springframework/security/config/ConfigUtils.java
@@ -0,0 +1,78 @@
+package org.springframework.security.config;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.security.AccessDecisionManager;
+import org.springframework.security.AuthenticationManager;
+import org.springframework.security.vote.AffirmativeBased;
+import org.springframework.security.vote.AuthenticatedVoter;
+import org.springframework.security.vote.RoleVoter;
+import org.springframework.util.Assert;
+
+import java.util.Arrays;
+import java.util.Map;
+
+/**
+ * @author Luke Taylor
+ * @version $Id$
+ */
+public abstract class ConfigUtils {
+ public static final String DEFAULT_ACCESS_MANAGER_ID = "_accessManager";
+
+ static void registerAccessManagerIfNecessary(ConfigurableListableBeanFactory bf) {
+ if (bf.getBeanNamesForType(AccessDecisionManager.class).length > 0) {
+ return;
+ }
+
+ Assert.isInstanceOf(BeanDefinitionRegistry.class, bf, " Auto-registration of default AccessManager will only work " +
+ "with a BeanFactory which implements BeanDefinitionRegistry");
+
+ BeanDefinitionRegistry registry = (BeanDefinitionRegistry)bf;
+
+ if (!registry.containsBeanDefinition(DEFAULT_ACCESS_MANAGER_ID)) {
+ BeanDefinitionBuilder accessMgrBuilder = BeanDefinitionBuilder.rootBeanDefinition(AffirmativeBased.class);
+ accessMgrBuilder.addPropertyValue("decisionVoters",
+ Arrays.asList(new Object[] {new RoleVoter(), new AuthenticatedVoter()}));
+ BeanDefinition accessMgr = accessMgrBuilder.getBeanDefinition();
+
+ registry.registerBeanDefinition(DEFAULT_ACCESS_MANAGER_ID, accessMgr);
+ }
+ }
+
+ static AuthenticationManager getAuthenticationManager(ConfigurableListableBeanFactory bf) {
+ Map authManagers = bf.getBeansOfType(AuthenticationManager.class);
+
+ if (authManagers.size() == 0) {
+ throw new IllegalArgumentException("No AuthenticationManager registered. " +
+ "Make sure you have configured at least one AuthenticationProvider?");
+
+ } else if (authManagers.size() > 1) {
+ throw new IllegalArgumentException("More than one AuthenticationManager registered.");
+ }
+
+ AuthenticationManager accessMgr = (AuthenticationManager) authManagers.values().toArray()[0];
+
+ return accessMgr;
+ }
+
+ static void configureSecurityInterceptor(ConfigurableListableBeanFactory beanFactory,
+ BeanDefinition securityInterceptor) {
+
+ ConfigUtils.registerAccessManagerIfNecessary(beanFactory);
+
+ Map accessManagers = beanFactory.getBeansOfType(AccessDecisionManager.class);
+
+ if (accessManagers.size() > 1) {
+ throw new IllegalArgumentException("More than one AccessDecisionManager registered. Please specify one " +
+ " using the TODO attribute.");
+ }
+
+ AccessDecisionManager accessMgr = (AccessDecisionManager) accessManagers.values().toArray()[0];
+
+ securityInterceptor.getPropertyValues().addPropertyValue("accessDecisionManager", accessMgr);
+ securityInterceptor.getPropertyValues().addPropertyValue("authenticationManager",
+ getAuthenticationManager(beanFactory));
+ }
+}
diff --git a/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java
index e323af7a14..464314dd55 100644
--- a/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java
+++ b/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java
@@ -88,7 +88,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
filterSecurityInterceptorBuilder.addPropertyValue("objectDefinitionSource", interceptorFilterInvDefSource);
// Again pick up auth manager
- filterSecurityInterceptorBuilder.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
+ //filterSecurityInterceptorBuilder.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
parseInterceptUrls(DomUtils.getChildElementsByTagName(element, "intercept-url"),
filterChainMap, interceptorFilterInvDefSource);
diff --git a/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java b/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java
index 01176e11ea..f1eab2e57b 100644
--- a/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java
+++ b/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java
@@ -8,6 +8,7 @@ import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.OrderComparator;
import org.springframework.core.Ordered;
+import org.springframework.security.AccessDecisionManager;
import org.springframework.security.AuthenticationManager;
import org.springframework.security.context.HttpSessionContextIntegrationFilter;
import org.springframework.security.ui.AuthenticationEntryPoint;
@@ -15,7 +16,11 @@ import org.springframework.security.util.FilterChainProxy;
import org.springframework.util.Assert;
import javax.servlet.Filter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
/**
* Responsible for tying up the HTTP security configuration - building ordered filter stack and linking up
@@ -26,18 +31,29 @@ import java.util.*;
*/
public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor, Ordered {
private Log logger = LogFactory.getLog(getClass());
+ private AuthenticationManager authManager;
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
HttpSessionContextIntegrationFilter httpSCIF = (HttpSessionContextIntegrationFilter)
beanFactory.getBean(HttpSecurityBeanDefinitionParser.DEFAULT_HTTP_SESSION_FILTER_ID);
- AuthenticationManager authManager =
- (AuthenticationManager) getBeanOfType(AuthenticationManager.class, beanFactory);
+ authManager = ConfigUtils.getAuthenticationManager(beanFactory);
configureAuthenticationEntryPoint(beanFactory);
+ configureFilterSecurityInterceptor(beanFactory);
+
configureFilterChain(beanFactory);
}
+ private void configureFilterSecurityInterceptor(ConfigurableListableBeanFactory beanFactory) {
+ ConfigUtils.registerAccessManagerIfNecessary(beanFactory);
+
+ BeanDefinition securityInterceptor =
+ beanFactory.getBeanDefinition(HttpSecurityBeanDefinitionParser.DEFAULT_FILTER_SECURITY_INTERCEPTOR_ID);
+
+ ConfigUtils.configureSecurityInterceptor(beanFactory, securityInterceptor);
+ }
+
/**
* Selects the entry point that should be used in ExceptionTranslationFilter. Strategy is
*
@@ -127,6 +143,6 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
}
public int getOrder() {
- return 0;
+ return HIGHEST_PRECEDENCE;
}
}
diff --git a/core/src/main/java/org/springframework/security/config/InterceptMethodsBeanDefinitionDecorator.java b/core/src/main/java/org/springframework/security/config/InterceptMethodsBeanDefinitionDecorator.java
index 56ad3a98d8..a6b7d26bf7 100644
--- a/core/src/main/java/org/springframework/security/config/InterceptMethodsBeanDefinitionDecorator.java
+++ b/core/src/main/java/org/springframework/security/config/InterceptMethodsBeanDefinitionDecorator.java
@@ -1,24 +1,78 @@
package org.springframework.security.config;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.springframework.aop.config.AbstractInterceptorDrivenBeanDefinitionDecorator;
+import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor;
-import org.springframework.security.intercept.method.MethodDefinitionMap;
-import org.springframework.security.ConfigAttributeEditor;
+import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.core.Ordered;
import org.springframework.security.ConfigAttributeDefinition;
+import org.springframework.security.ConfigAttributeEditor;
+import org.springframework.security.intercept.method.MethodDefinitionMap;
+import org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor;
import org.springframework.util.xml.DomUtils;
-import org.w3c.dom.Node;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
-import java.util.List;
import java.util.Iterator;
+import java.util.List;
/**
* @author Luke Taylor
* @version $Id$
*/
-public class InterceptMethodsBeanDefinitionDecorator extends AbstractInterceptorDrivenBeanDefinitionDecorator {
+public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDecorator {
+ private static final String POST_PROCESSOR_ID = "_interceptMethodsBeanfactoryPP";
+
+ private BeanDefinitionDecorator delegate = new InternalInterceptMethodsBeanDefinitionDecorator();
+
+ public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
+ registerPostProcessorIfNecessary(parserContext.getRegistry());
+
+ return delegate.decorate(node, definition, parserContext);
+ }
+
+ private void registerPostProcessorIfNecessary(BeanDefinitionRegistry registry) {
+ if (registry.containsBeanDefinition(POST_PROCESSOR_ID)) {
+ return;
+ }
+
+ registry.registerBeanDefinition(POST_PROCESSOR_ID,
+ new RootBeanDefinition(MethodSecurityConfigPostProcessor.class));
+ }
+
+ public static class MethodSecurityConfigPostProcessor implements BeanFactoryPostProcessor, Ordered {
+
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ String[] interceptors = beanFactory.getBeanNamesForType(MethodSecurityInterceptor.class);
+
+ for (int i=0; i < interceptors.length; i++) {
+ BeanDefinition interceptor = beanFactory.getBeanDefinition(interceptors[i]);
+ ConfigUtils.configureSecurityInterceptor(beanFactory, interceptor);
+ }
+ }
+
+ public int getOrder() {
+ return HIGHEST_PRECEDENCE;
+ }
+
+ }
+}
+
+/**
+ * This is the real class which does the work. We need acccess to the ParserContext in order to register the
+ * post processor,
+ */
+class InternalInterceptMethodsBeanDefinitionDecorator extends AbstractInterceptorDrivenBeanDefinitionDecorator {
+ private Log logger = LogFactory.getLog(getClass());
+
protected BeanDefinition createInterceptorDefinition(Node node) {
Element interceptMethodsElt = (Element)node;
RootBeanDefinition interceptor = new RootBeanDefinition(MethodSecurityInterceptor.class);
@@ -53,8 +107,6 @@ public class InterceptMethodsBeanDefinitionDecorator extends AbstractInterceptor
interceptor.getPropertyValues().addPropertyValue("objectDefinitionSource", methodMap);
- interceptor.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
-
return interceptor;
}
}
diff --git a/core/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java b/core/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java
index c1f13bee21..7f477fcf90 100644
--- a/core/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java
+++ b/core/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java
@@ -15,7 +15,6 @@ public class SecurityNamespaceHandler extends NamespaceHandlerSupport {
registerBeanDefinitionParser("http", new HttpSecurityBeanDefinitionParser());
registerBeanDefinitionParser("user-service", new UserServiceBeanDefinitionParser());
registerBeanDefinitionParser("authentication-provider", new AuthenticationProviderBeanDefinitionParser());
- registerBeanDefinitionParser("autoconfig", new AutoConfigBeanDefinitionParser());
registerBeanDefinitionDecorator("intercept-methods", new InterceptMethodsBeanDefinitionDecorator());
registerBeanDefinitionDecorator("filter-chain-map", new FilterChainMapBeanDefinitionDecorator());
}
diff --git a/core/src/test/resources/org/springframework/security/config/http-security.xml b/core/src/test/resources/org/springframework/security/config/http-security.xml
index 616f87f682..15b921937f 100644
--- a/core/src/test/resources/org/springframework/security/config/http-security.xml
+++ b/core/src/test/resources/org/springframework/security/config/http-security.xml
@@ -6,8 +6,6 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
-
-
@@ -23,12 +21,10 @@ http://www.springframework.org/schema/security http://www.springframework.org/sc
-
-
\ No newline at end of file
diff --git a/core/src/test/resources/org/springframework/security/config/method-security.xml b/core/src/test/resources/org/springframework/security/config/method-security.xml
index a25c205b71..3ba61d90fd 100644
--- a/core/src/test/resources/org/springframework/security/config/method-security.xml
+++ b/core/src/test/resources/org/springframework/security/config/method-security.xml
@@ -6,8 +6,6 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
-
-