Remove use of autoconfig, as it was really just a conveniece for creating default access and authentication managers.
This commit is contained in:
parent
700de0d388
commit
1bcb62af2e
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue