Remove use of autoconfig, as it was really just a conveniece for creating default access and authentication managers.

This commit is contained in:
Luke Taylor 2007-10-26 13:05:31 +00:00
parent 700de0d388
commit 1bcb62af2e
7 changed files with 159 additions and 20 deletions

View File

@ -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));
}
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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());
}

View File

@ -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">
<security:autoconfig />
<security:http createSession="ifRequired" pathType="ant" lowerCaseComparisons="true">
<security:intercept-url pattern="/unprotected" filters="none"/>
<security:intercept-url pattern="/somepath" access="ROLE_SPECIAL,ROLE_USER" />
@ -23,12 +21,10 @@ http://www.springframework.org/schema/security http://www.springframework.org/sc
<security:http-basic realm="NamespaceTestRealm" />
</security:http>
<security:authentication-provider>
<security:user-service>
<security:user name="bob" password="bobspassword" authorities="ROLE_A,ROLE_B" />
<security:user name="bill" password="billspassword" authorities="ROLE_A,ROLE_B,AUTH_OTHER" />
</security:user-service>
</security:authentication-provider>
</beans>

View File

@ -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">
<security:autoconfig />
<bean id="target" class="org.springframework.security.config.TestBusinessBeanImpl">
<!-- This will add a security interceptor to the bean -->
<security:intercept-methods>