Moved configuration of security interceptors with access and authentication manangers from post processing stage to bean creation stage.
This commit is contained in:
parent
46c99d1991
commit
5f1eea42fc
|
@ -0,0 +1,70 @@
|
||||||
|
package org.springframework.security.config;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
import org.springframework.security.AccessDeniedException;
|
||||||
|
import org.springframework.security.AuthenticationCredentialsNotFoundException;
|
||||||
|
import org.springframework.security.GrantedAuthority;
|
||||||
|
import org.springframework.security.GrantedAuthorityImpl;
|
||||||
|
import org.springframework.security.annotation.BusinessService;
|
||||||
|
import org.springframework.security.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ben Alex
|
||||||
|
* @version $Id: InterceptMethodsBeanDefinitionDecoratorTests.java 2217 2007-10-27 00:45:30Z luke_t $
|
||||||
|
*/
|
||||||
|
public class AnnotationDrivenBeanDefinitionParserTests {
|
||||||
|
private ClassPathXmlApplicationContext appContext;
|
||||||
|
|
||||||
|
private BusinessService target;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void loadContext() {
|
||||||
|
appContext = new ClassPathXmlApplicationContext("org/springframework/security/config/annotated-method-security.xml");
|
||||||
|
target = (BusinessService) appContext.getBean("target");
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void closeAppContext() {
|
||||||
|
if (appContext != null) {
|
||||||
|
appContext.close();
|
||||||
|
}
|
||||||
|
SecurityContextHolder.clearContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void targetShouldPreventProtectedMethodInvocationWithNoContext() {
|
||||||
|
try {
|
||||||
|
target.someUserMethod1();
|
||||||
|
fail("Expected AuthenticationCredentialsNotFoundException");
|
||||||
|
} catch (AuthenticationCredentialsNotFoundException expected) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void targetShouldAllowProtectedMethodInvocationWithCorrectRole() {
|
||||||
|
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
|
||||||
|
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_USER")});
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(token);
|
||||||
|
|
||||||
|
target.someUserMethod1();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void targetShouldPreventProtectedMethodInvocationWithIncorrectRole() {
|
||||||
|
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
|
||||||
|
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_SOMEOTHERROLE")});
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(token);
|
||||||
|
|
||||||
|
try {
|
||||||
|
target.someAdminMethod();
|
||||||
|
fail("Expected AccessDeniedException");
|
||||||
|
} catch (AccessDeniedException expected) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,18 +12,21 @@ import org.springframework.security.intercept.method.aopalliance.MethodSecurityI
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes the top-level "annotation-driven" element.
|
* Processes the top-level "annotation-driven" element.
|
||||||
*
|
*
|
||||||
* @author Ben Alex
|
* @author Ben Alex
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
|
|
||||||
public static final String SECURITY_ANNOTATION_ATTRIBUTES_CLASS = "org.springframework.security.annotation.SecurityAnnotationAttributes";
|
public static final String SECURITY_ANNOTATION_ATTRIBUTES_CLASS = "org.springframework.security.annotation.SecurityAnnotationAttributes";
|
||||||
|
private static final String ATT_ACCESS_MGR = "access-decision-manager";
|
||||||
|
|
||||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||||
// Reflectively obtain the Annotation-based ObjectDefinitionSource.
|
// Reflectively obtain the Annotation-based ObjectDefinitionSource.
|
||||||
// Reflection is used to avoid a compile-time dependency on SECURITY_ANNOTATION_ATTRIBUTES_CLASS, as this parser is in the Java 4 project whereas the dependency is in the Tiger project.
|
// Reflection is used to avoid a compile-time dependency on SECURITY_ANNOTATION_ATTRIBUTES_CLASS, as this parser is in the Java 4 project whereas the dependency is in the Tiger project.
|
||||||
|
@ -34,26 +37,38 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ReflectionUtils.handleReflectionException(ex);
|
ReflectionUtils.handleReflectionException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
RootBeanDefinition securityAnnotations = new RootBeanDefinition(clazz);
|
RootBeanDefinition securityAnnotations = new RootBeanDefinition(clazz);
|
||||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.SECURITY_ANNOTATION_ATTRIBUTES, securityAnnotations);
|
parserContext.getRegistry().registerBeanDefinition(BeanIds.SECURITY_ANNOTATION_ATTRIBUTES, securityAnnotations);
|
||||||
|
|
||||||
RootBeanDefinition methodDefinitionAttributes = new RootBeanDefinition(MethodDefinitionAttributes.class);
|
RootBeanDefinition methodDefinitionAttributes = new RootBeanDefinition(MethodDefinitionAttributes.class);
|
||||||
methodDefinitionAttributes.getPropertyValues().addPropertyValue("attributes", new RuntimeBeanReference(BeanIds.SECURITY_ANNOTATION_ATTRIBUTES));
|
methodDefinitionAttributes.getPropertyValues().addPropertyValue("attributes", new RuntimeBeanReference(BeanIds.SECURITY_ANNOTATION_ATTRIBUTES));
|
||||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_DEFINITION_ATTRIBUTES, methodDefinitionAttributes);
|
parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_DEFINITION_ATTRIBUTES, methodDefinitionAttributes);
|
||||||
|
|
||||||
MethodSecurityInterceptorUtils.registerPostProcessorIfNecessary(parserContext.getRegistry());
|
|
||||||
|
|
||||||
RootBeanDefinition interceptor = new RootBeanDefinition(MethodSecurityInterceptor.class);
|
RootBeanDefinition interceptor = new RootBeanDefinition(MethodSecurityInterceptor.class);
|
||||||
|
|
||||||
|
String accessManagerId = element.getAttribute(ATT_ACCESS_MGR);
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(accessManagerId)) {
|
||||||
|
ConfigUtils.registerDefaultAccessManagerIfNecessary(parserContext);
|
||||||
|
accessManagerId = BeanIds.ACCESS_MANAGER;
|
||||||
|
}
|
||||||
|
|
||||||
|
interceptor.getPropertyValues().addPropertyValue("accessDecisionManager",
|
||||||
|
new RuntimeBeanReference(accessManagerId));
|
||||||
|
|
||||||
|
interceptor.getPropertyValues().addPropertyValue("authenticationManager",
|
||||||
|
new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
|
||||||
|
|
||||||
interceptor.getPropertyValues().addPropertyValue("objectDefinitionSource", new RuntimeBeanReference(BeanIds.METHOD_DEFINITION_ATTRIBUTES));
|
interceptor.getPropertyValues().addPropertyValue("objectDefinitionSource", new RuntimeBeanReference(BeanIds.METHOD_DEFINITION_ATTRIBUTES));
|
||||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_SECURITY_INTERCEPTOR, interceptor);
|
parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_SECURITY_INTERCEPTOR, interceptor);
|
||||||
|
|
||||||
RootBeanDefinition advisor = new RootBeanDefinition(MethodDefinitionSourceAdvisor.class);
|
RootBeanDefinition advisor = new RootBeanDefinition(MethodDefinitionSourceAdvisor.class);
|
||||||
advisor.getConstructorArgumentValues().addGenericArgumentValue(interceptor);
|
advisor.getConstructorArgumentValues().addGenericArgumentValue(interceptor);
|
||||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_DEFINITION_SOURCE_ADVISOR, advisor);
|
parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_DEFINITION_SOURCE_ADVISOR, advisor);
|
||||||
|
|
||||||
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
|
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,18 @@ package org.springframework.security.config;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
|
||||||
import org.springframework.beans.factory.support.ManagedList;
|
import org.springframework.beans.factory.support.ManagedList;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.security.AccessDecisionManager;
|
|
||||||
import org.springframework.security.AuthenticationManager;
|
import org.springframework.security.AuthenticationManager;
|
||||||
import org.springframework.security.providers.ProviderManager;
|
import org.springframework.security.providers.ProviderManager;
|
||||||
import org.springframework.security.userdetails.UserDetailsService;
|
import org.springframework.security.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.vote.AffirmativeBased;
|
import org.springframework.security.vote.AffirmativeBased;
|
||||||
import org.springframework.security.vote.AuthenticatedVoter;
|
import org.springframework.security.vote.AuthenticatedVoter;
|
||||||
import org.springframework.security.vote.RoleVoter;
|
import org.springframework.security.vote.RoleVoter;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -27,23 +27,17 @@ import java.util.Map;
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public abstract class ConfigUtils {
|
public abstract class ConfigUtils {
|
||||||
static void registerAccessManagerIfNecessary(ConfigurableListableBeanFactory bf) {
|
private static final Log logger = LogFactory.getLog(ConfigUtils.class);
|
||||||
if (bf.getBeanNamesForType(AccessDecisionManager.class).length > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert.isInstanceOf(BeanDefinitionRegistry.class, bf, "Auto-registration of default AccessManager will " +
|
static void registerDefaultAccessManagerIfNecessary(ParserContext parserContext) {
|
||||||
"only work with a BeanFactory which implements BeanDefinitionRegistry");
|
|
||||||
|
|
||||||
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)bf;
|
if (!parserContext.getRegistry().containsBeanDefinition(BeanIds.ACCESS_MANAGER)) {
|
||||||
|
|
||||||
if (!registry.containsBeanDefinition(BeanIds.ACCESS_MANAGER)) {
|
|
||||||
BeanDefinitionBuilder accessMgrBuilder = BeanDefinitionBuilder.rootBeanDefinition(AffirmativeBased.class);
|
BeanDefinitionBuilder accessMgrBuilder = BeanDefinitionBuilder.rootBeanDefinition(AffirmativeBased.class);
|
||||||
accessMgrBuilder.addPropertyValue("decisionVoters",
|
accessMgrBuilder.addPropertyValue("decisionVoters",
|
||||||
Arrays.asList(new Object[] {new RoleVoter(), new AuthenticatedVoter()}));
|
Arrays.asList(new Object[] {new RoleVoter(), new AuthenticatedVoter()}));
|
||||||
BeanDefinition accessMgr = accessMgrBuilder.getBeanDefinition();
|
BeanDefinition accessMgr = accessMgrBuilder.getBeanDefinition();
|
||||||
|
|
||||||
registry.registerBeanDefinition(BeanIds.ACCESS_MANAGER, accessMgr);
|
parserContext.getRegistry().registerBeanDefinition(BeanIds.ACCESS_MANAGER, accessMgr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,32 +60,6 @@ public abstract class ConfigUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Supplies the BeanDefinition for an instance of AbstractSecurityInterceptor with the default
|
|
||||||
* AccessDecisionManager and AuthenticationManager.
|
|
||||||
*
|
|
||||||
* @param beanFactory
|
|
||||||
* @param securityInterceptor
|
|
||||||
*/
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
static UserDetailsService getUserDetailsService(ConfigurableListableBeanFactory bf) {
|
static UserDetailsService getUserDetailsService(ConfigurableListableBeanFactory bf) {
|
||||||
Map services = bf.getBeansOfType(UserDetailsService.class);
|
Map services = bf.getBeansOfType(UserDetailsService.class);
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,8 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
static final String ATT_SERVLET_API_PROVISION = "servlet-api-provision";
|
static final String ATT_SERVLET_API_PROVISION = "servlet-api-provision";
|
||||||
static final String DEF_SERVLET_API_PROVISION = "true";
|
static final String DEF_SERVLET_API_PROVISION = "true";
|
||||||
|
|
||||||
|
static final String ATT_ACCESS_MGR = "access-decision-manager";
|
||||||
|
|
||||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||||
RootBeanDefinition filterChainProxy = new RootBeanDefinition(FilterChainProxy.class);
|
RootBeanDefinition filterChainProxy = new RootBeanDefinition(FilterChainProxy.class);
|
||||||
RootBeanDefinition httpScif = new RootBeanDefinition(HttpSessionContextIntegrationFilter.class);
|
RootBeanDefinition httpScif = new RootBeanDefinition(HttpSessionContextIntegrationFilter.class);
|
||||||
|
@ -139,6 +141,19 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
|
|
||||||
filterSecurityInterceptorBuilder.addPropertyValue("objectDefinitionSource", interceptorFilterInvDefSource);
|
filterSecurityInterceptorBuilder.addPropertyValue("objectDefinitionSource", interceptorFilterInvDefSource);
|
||||||
|
|
||||||
|
// Set up the access manager and authentication mananger references for http
|
||||||
|
String accessManagerId = element.getAttribute(ATT_ACCESS_MGR);
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(accessManagerId)) {
|
||||||
|
ConfigUtils.registerDefaultAccessManagerIfNecessary(parserContext);
|
||||||
|
accessManagerId = BeanIds.ACCESS_MANAGER;
|
||||||
|
}
|
||||||
|
|
||||||
|
filterSecurityInterceptorBuilder.addPropertyValue("accessDecisionManager",
|
||||||
|
new RuntimeBeanReference(accessManagerId));
|
||||||
|
filterSecurityInterceptorBuilder.addPropertyValue("authenticationManager",
|
||||||
|
ConfigUtils.registerProviderManagerIfNecessary(parserContext));
|
||||||
|
|
||||||
parseInterceptUrls(DomUtils.getChildElementsByTagName(element, "intercept-url"),
|
parseInterceptUrls(DomUtils.getChildElementsByTagName(element, "intercept-url"),
|
||||||
filterChainMap, interceptorFilterInvDefSource, channelFilterInvDefSource, parserContext);
|
filterChainMap, interceptorFilterInvDefSource, channelFilterInvDefSource, parserContext);
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,6 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
|
||||||
private Log logger = LogFactory.getLog(getClass());
|
private Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||||
ConfigUtils.registerAccessManagerIfNecessary(beanFactory);
|
|
||||||
BeanDefinition securityInterceptor =
|
|
||||||
beanFactory.getBeanDefinition(BeanIds.FILTER_SECURITY_INTERCEPTOR);
|
|
||||||
|
|
||||||
ConfigUtils.configureSecurityInterceptor(beanFactory, securityInterceptor);
|
|
||||||
|
|
||||||
injectUserDetailsServiceIntoRememberMeServices(beanFactory);
|
injectUserDetailsServiceIntoRememberMeServices(beanFactory);
|
||||||
|
|
||||||
injectAuthenticationEntryPointIntoExceptionTranslationFilter(beanFactory);
|
injectAuthenticationEntryPointIntoExceptionTranslationFilter(beanFactory);
|
||||||
|
@ -55,8 +49,7 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
|
||||||
|
|
||||||
private void injectUserDetailsServiceIntoRememberMeServices(ConfigurableListableBeanFactory beanFactory) {
|
private void injectUserDetailsServiceIntoRememberMeServices(ConfigurableListableBeanFactory beanFactory) {
|
||||||
try {
|
try {
|
||||||
BeanDefinition rememberMeServices =
|
BeanDefinition rememberMeServices = beanFactory.getBeanDefinition(BeanIds.REMEMBER_ME_SERVICES);
|
||||||
beanFactory.getBeanDefinition(BeanIds.REMEMBER_ME_SERVICES);
|
|
||||||
rememberMeServices.getPropertyValues().addPropertyValue("userDetailsService",
|
rememberMeServices.getPropertyValues().addPropertyValue("userDetailsService",
|
||||||
ConfigUtils.getUserDetailsService(beanFactory));
|
ConfigUtils.getUserDetailsService(beanFactory));
|
||||||
} catch (NoSuchBeanDefinitionException e) {
|
} catch (NoSuchBeanDefinitionException e) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.aop.config.AbstractInterceptorDrivenBeanDefinitionDecorator;
|
import org.springframework.aop.config.AbstractInterceptorDrivenBeanDefinitionDecorator;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||||
|
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
|
import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
|
@ -13,6 +14,8 @@ import org.springframework.security.ConfigAttributeEditor;
|
||||||
import org.springframework.security.intercept.method.MethodDefinitionMap;
|
import org.springframework.security.intercept.method.MethodDefinitionMap;
|
||||||
import org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor;
|
import org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor;
|
||||||
import org.springframework.util.xml.DomUtils;
|
import org.springframework.util.xml.DomUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
|
@ -22,33 +25,48 @@ import java.util.List;
|
||||||
/**
|
/**
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
* @author Ben Alex
|
* @author Ben Alex
|
||||||
*
|
*
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDecorator {
|
public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDecorator {
|
||||||
private BeanDefinitionDecorator delegate = new InternalInterceptMethodsBeanDefinitionDecorator();
|
private BeanDefinitionDecorator delegate = new InternalInterceptMethodsBeanDefinitionDecorator();
|
||||||
|
|
||||||
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
|
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
|
||||||
MethodSecurityInterceptorUtils.registerPostProcessorIfNecessary(parserContext.getRegistry());
|
ConfigUtils.registerProviderManagerIfNecessary(parserContext);
|
||||||
|
ConfigUtils.registerDefaultAccessManagerIfNecessary(parserContext);
|
||||||
|
|
||||||
return delegate.decorate(node, definition, parserContext);
|
return delegate.decorate(node, definition, parserContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the real class which does the work. We need acccess to the ParserContext in order to register the
|
* This is the real class which does the work. We need acccess to the ParserContext in order to do bean
|
||||||
* post processor,
|
* registration.
|
||||||
*/
|
*/
|
||||||
class InternalInterceptMethodsBeanDefinitionDecorator extends AbstractInterceptorDrivenBeanDefinitionDecorator {
|
class InternalInterceptMethodsBeanDefinitionDecorator extends AbstractInterceptorDrivenBeanDefinitionDecorator {
|
||||||
static final String ATT_CLASS = "class";
|
static final String ATT_CLASS = "class";
|
||||||
static final String ATT_METHOD = "method";
|
static final String ATT_METHOD = "method";
|
||||||
static final String ATT_ACCESS = "access";
|
static final String ATT_ACCESS = "access";
|
||||||
private Log logger = LogFactory.getLog(getClass());
|
private static final String ATT_ACCESS_MGR = "access-decision-manager";
|
||||||
|
|
||||||
|
private Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
protected BeanDefinition createInterceptorDefinition(Node node) {
|
protected BeanDefinition createInterceptorDefinition(Node node) {
|
||||||
Element interceptMethodsElt = (Element)node;
|
Element interceptMethodsElt = (Element)node;
|
||||||
RootBeanDefinition interceptor = new RootBeanDefinition(MethodSecurityInterceptor.class);
|
RootBeanDefinition interceptor = new RootBeanDefinition(MethodSecurityInterceptor.class);
|
||||||
|
|
||||||
|
String accessManagerId = interceptMethodsElt.getAttribute(ATT_ACCESS_MGR);
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(accessManagerId)) {
|
||||||
|
accessManagerId = BeanIds.ACCESS_MANAGER;
|
||||||
|
}
|
||||||
|
|
||||||
|
interceptor.getPropertyValues().addPropertyValue("accessDecisionManager",
|
||||||
|
new RuntimeBeanReference(accessManagerId));
|
||||||
|
|
||||||
|
interceptor.getPropertyValues().addPropertyValue("authenticationManager",
|
||||||
|
new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
|
||||||
|
|
||||||
Element beanNode = (Element)interceptMethodsElt.getParentNode();
|
Element beanNode = (Element)interceptMethodsElt.getParentNode();
|
||||||
// Get the class from the parent bean...
|
// Get the class from the parent bean...
|
||||||
String targetClassName = beanNode.getAttribute(ATT_CLASS);
|
String targetClassName = beanNode.getAttribute(ATT_CLASS);
|
||||||
|
@ -57,7 +75,8 @@ class InternalInterceptMethodsBeanDefinitionDecorator extends AbstractIntercepto
|
||||||
try {
|
try {
|
||||||
targetClass = Thread.currentThread().getContextClassLoader().loadClass(targetClassName);
|
targetClass = Thread.currentThread().getContextClassLoader().loadClass(targetClassName);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
throw new IllegalArgumentException("Couldn't load class " + targetClassName, e);
|
logger.error("Couldn't load class " + targetClassName);
|
||||||
|
throw new SecurityConfigurationException("Couldn't load class " + targetClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the included methods
|
// Parse the included methods
|
||||||
|
@ -70,10 +89,10 @@ class InternalInterceptMethodsBeanDefinitionDecorator extends AbstractIntercepto
|
||||||
String accessConfig = protectmethodElt.getAttribute(ATT_ACCESS);
|
String accessConfig = protectmethodElt.getAttribute(ATT_ACCESS);
|
||||||
attributeEditor.setAsText(accessConfig);
|
attributeEditor.setAsText(accessConfig);
|
||||||
|
|
||||||
// TODO: We want to use just the method names, but MethodDefinitionMap won't work that way.
|
// TODO: We want to use just the method names, but MethodDefinitionMap won't work that way.
|
||||||
// methodMap.addSecureMethod(targetClass, protectmethodElt.getAttribute("method"),
|
// methodMap.addSecureMethod(targetClass, protectmethodElt.getAttribute("method"),
|
||||||
// (ConfigAttributeDefinition) attributeEditor.getValue());
|
// (ConfigAttributeDefinition) attributeEditor.getValue());
|
||||||
methodMap.addSecureMethod(protectmethodElt.getAttribute(ATT_METHOD),
|
methodMap.addSecureMethod(protectmethodElt.getAttribute(ATT_METHOD),
|
||||||
(ConfigAttributeDefinition) attributeEditor.getValue());
|
(ConfigAttributeDefinition) attributeEditor.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
package org.springframework.security.config;
|
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
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.core.Ordered;
|
|
||||||
import org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides convenience methods supporting method security configuration.
|
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @author Luke Taylor
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
abstract class MethodSecurityInterceptorUtils {
|
|
||||||
|
|
||||||
private 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes a BeanFactoryPostProcessor to be registered that will ensure all MethodSecurityInterceptor
|
|
||||||
* instances are properly configured with an AccessDecisionManager etc.
|
|
||||||
*
|
|
||||||
* @param registry to register the BeanPostProcessorWith
|
|
||||||
*/
|
|
||||||
public static void registerPostProcessorIfNecessary(BeanDefinitionRegistry registry) {
|
|
||||||
if (registry.containsBeanDefinition(BeanIds.INTERCEPT_METHODS_BEAN_FACTORY_POST_PROCESSOR)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
registry.registerBeanDefinition(BeanIds.INTERCEPT_METHODS_BEAN_FACTORY_POST_PROCESSOR,
|
|
||||||
new RootBeanDefinition(MethodSecurityInterceptorUtils.MethodSecurityConfigPostProcessor.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -16,29 +16,21 @@ import org.junit.*;
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class InterceptMethodsBeanDefinitionDecoratorTests {
|
public class InterceptMethodsBeanDefinitionDecoratorTests {
|
||||||
private static ClassPathXmlApplicationContext appContext;
|
private ClassPathXmlApplicationContext appContext;
|
||||||
|
|
||||||
private TestBusinessBean target;
|
private TestBusinessBean target;
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void loadContext() {
|
|
||||||
appContext = new ClassPathXmlApplicationContext("org/springframework/security/config/method-security.xml");
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void closeAppContext() {
|
|
||||||
if (appContext != null) {
|
|
||||||
appContext.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void loadContext() {
|
||||||
|
appContext = new ClassPathXmlApplicationContext("org/springframework/security/config/method-security.xml");
|
||||||
target = (TestBusinessBean) appContext.getBean("target");
|
target = (TestBusinessBean) appContext.getBean("target");
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void clearSecurityContext() {
|
public void closeAppContext() {
|
||||||
|
if (appContext != null) {
|
||||||
|
appContext.close();
|
||||||
|
}
|
||||||
SecurityContextHolder.clearContext();
|
SecurityContextHolder.clearContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,7 @@
|
||||||
to the Contact presented as a method argument.
|
to the Contact presented as a method argument.
|
||||||
-->
|
-->
|
||||||
<bean id="contactManagerSecurity" class="org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor">
|
<bean id="contactManagerSecurity" class="org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||||
<property name="authenticationManager" ref="authenticationManager"/>
|
<property name="authenticationManager" ref="_authenticationManager"/>
|
||||||
<property name="accessDecisionManager">
|
<property name="accessDecisionManager">
|
||||||
<ref local="businessAccessDecisionManager"/>
|
<ref local="businessAccessDecisionManager"/>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- Application context containing business beans.
|
- Application context containing business beans.
|
||||||
|
@ -9,7 +8,11 @@
|
||||||
- $Id$
|
- $Id$
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<beans>
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:security="http://www.springframework.org/schema/security"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
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">
|
||||||
|
|
||||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
||||||
|
@ -55,12 +58,12 @@
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="contactManagerTarget" class="sample.contact.ContactManagerBackend">
|
<bean id="contactManagerTarget" class="sample.contact.ContactManagerBackend">
|
||||||
<property name="contactDao">
|
<property name="contactDao">
|
||||||
<bean class="sample.contact.ContactDaoSpring">
|
<bean class="sample.contact.ContactDaoSpring">
|
||||||
<property name="dataSource"><ref local="dataSource"/></property>
|
<property name="dataSource"><ref local="dataSource"/></property>
|
||||||
</bean>
|
</bean>
|
||||||
</property>
|
</property>
|
||||||
<property name="mutableAclService" ref="aclService"/>
|
<property name="mutableAclService" ref="aclService"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- Application context containing authentication, channel
|
- Application context containing authentication, channel
|
||||||
- security and web URI beans.
|
- security and web URI beans.
|
||||||
|
@ -10,84 +8,55 @@
|
||||||
- $Id: applicationContext-acegi-security.xml 1425 2006-04-28 06:43:50Z benalex $
|
- $Id: applicationContext-acegi-security.xml 1425 2006-04-28 06:43:50Z benalex $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<beans>
|
<b:beans xmlns="http://www.springframework.org/schema/security"
|
||||||
|
xmlns:b="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
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">
|
||||||
|
|
||||||
<!-- ======================== FILTER CHAIN ======================= -->
|
|
||||||
|
|
||||||
<!-- if you wish to use channel security, add "channelProcessingFilter," in front
|
<http auto-config="true" realm="Contacts Realm">
|
||||||
of "httpSessionContextIntegrationFilter" in the list below -->
|
<intercept-url pattern="/index.jsp" access="ROLE_ANONYMOUS,ROLE_USER"/>
|
||||||
|
<intercept-url pattern="/hello.htm" access="ROLE_ANONYMOUS,ROLE_USER"/>
|
||||||
|
<intercept-url pattern="/switchuser.jsp" access="ROLE_SUPERVISOR"/>
|
||||||
|
<intercept-url pattern="/j_spring_security_switch_user" access="ROLE_SUPERVISOR"/>
|
||||||
|
<intercept-url pattern="/acegilogin.jsp*" access="ROLE_ANONYMOUS,ROLE_USER"/>
|
||||||
|
<intercept-url pattern="/**" access="ROLE_USER"/>
|
||||||
|
|
||||||
|
<form-login login-page="/acegilogin.jsp" authentication-failure-url="/acegilogin.jsp?login_error=1"/>
|
||||||
|
<logout logout-url="/index.jsp"/>
|
||||||
|
</http>
|
||||||
|
|
||||||
|
<!--
|
||||||
<bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy">
|
<bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy">
|
||||||
<property name="filterInvocationDefinitionSource">
|
<property name="filterInvocationDefinitionSource">
|
||||||
<value><![CDATA[
|
<value><![CDATA[
|
||||||
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
||||||
PATTERN_TYPE_APACHE_ANT
|
PATTERN_TYPE_APACHE_ANT
|
||||||
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,switchUserProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
|
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor,switchUserProcessingFilter
|
||||||
]]></value>
|
]]></value>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- ======================== AUTHENTICATION ======================= -->
|
|
||||||
|
|
||||||
<bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
|
|
||||||
<property name="providers">
|
|
||||||
<list>
|
|
||||||
<ref local="daoAuthenticationProvider"/>
|
|
||||||
<ref local="anonymousAuthenticationProvider"/>
|
|
||||||
<ref local="rememberMeAuthenticationProvider"/>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="jdbcDaoImpl" class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">
|
|
||||||
<property name="dataSource"><ref bean="dataSource"/></property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="passwordEncoder" class="org.springframework.security.providers.encoding.Md5PasswordEncoder"/>
|
|
||||||
|
|
||||||
<bean id="daoAuthenticationProvider" class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
|
|
||||||
<property name="userDetailsService"><ref local="jdbcDaoImpl"/></property>
|
|
||||||
<!-- <property name="userCache"><ref local="userCache"/></property> -->
|
|
||||||
<property name="passwordEncoder"><ref local="passwordEncoder"/></property>
|
|
||||||
</bean>
|
|
||||||
<!--
|
|
||||||
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
|
|
||||||
|
|
||||||
<bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
|
|
||||||
<property name="cacheManager">
|
|
||||||
<ref local="cacheManager"/>
|
|
||||||
</property>
|
|
||||||
<property name="cacheName">
|
|
||||||
<value>userCache</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="userCache" class="org.springframework.security.providers.dao.cache.EhCacheBasedUserCache">
|
|
||||||
<property name="cache"><ref local="userCacheBackend"/></property>
|
|
||||||
</bean>
|
|
||||||
-->
|
|
||||||
<!-- Automatically receives AuthenticationEvent messages -->
|
|
||||||
<bean id="loggerListener" class="org.springframework.security.event.authentication.LoggerListener"/>
|
|
||||||
|
|
||||||
<bean id="basicProcessingFilter" class="org.springframework.security.ui.basicauth.BasicProcessingFilter">
|
<bean id="basicProcessingFilter" class="org.springframework.security.ui.basicauth.BasicProcessingFilter">
|
||||||
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
||||||
<property name="authenticationEntryPoint"><ref local="basicProcessingFilterEntryPoint"/></property>
|
<property name="authenticationEntryPoint"><ref local="basicProcessingFilterEntryPoint"/></property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="basicProcessingFilterEntryPoint" class="org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint">
|
<bean id="basicProcessingFilterEntryPoint" class="org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint">
|
||||||
<property name="realmName"><value>Contacts Realm</value></property>
|
<property name="realmName" value="Contacts Realm"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="anonymousProcessingFilter" class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter">
|
<bean id="anonymousProcessingFilter" class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter">
|
||||||
<property name="key"><value>foobar</value></property>
|
<property name="key" value="foobar"/>
|
||||||
<property name="userAttribute"><value>anonymousUser,ROLE_ANONYMOUS</value></property>
|
<property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="anonymousAuthenticationProvider" class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider">
|
<bean id="anonymousAuthenticationProvider" class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider">
|
||||||
<property name="key"><value>foobar</value></property>
|
<property name="key" value="foobar"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="httpSessionContextIntegrationFilter" class="org.springframework.security.context.HttpSessionContextIntegrationFilter">
|
<bean id="httpSessionContextIntegrationFilter" class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="rememberMeProcessingFilter" class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter">
|
<bean id="rememberMeProcessingFilter" class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter">
|
||||||
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
||||||
|
@ -96,15 +65,15 @@
|
||||||
|
|
||||||
<bean id="rememberMeServices" class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices">
|
<bean id="rememberMeServices" class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices">
|
||||||
<property name="userDetailsService"><ref local="jdbcDaoImpl"/></property>
|
<property name="userDetailsService"><ref local="jdbcDaoImpl"/></property>
|
||||||
<property name="key"><value>springRocks</value></property>
|
<property name="key" value="springRocks"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="rememberMeAuthenticationProvider" class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider">
|
<bean id="rememberMeAuthenticationProvider" class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider">
|
||||||
<property name="key"><value>springRocks</value></property>
|
<property name="key" value="springRocks"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter">
|
<bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter">
|
||||||
<constructor-arg value="/index.jsp"/> <!-- URL redirected to after logout -->
|
<constructor-arg value="/index.jsp"/>
|
||||||
<constructor-arg>
|
<constructor-arg>
|
||||||
<list>
|
<list>
|
||||||
<ref bean="rememberMeServices"/>
|
<ref bean="rememberMeServices"/>
|
||||||
|
@ -115,38 +84,6 @@
|
||||||
|
|
||||||
<bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter"/>
|
<bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter"/>
|
||||||
|
|
||||||
<!-- ===================== HTTP CHANNEL REQUIREMENTS ==================== -->
|
|
||||||
|
|
||||||
<!-- You will need to uncomment the "Acegi Channel Processing Filter"
|
|
||||||
<filter-mapping> in web.xml for the following beans to be used -->
|
|
||||||
|
|
||||||
<bean id="channelProcessingFilter" class="org.springframework.security.securechannel.ChannelProcessingFilter">
|
|
||||||
<property name="channelDecisionManager"><ref local="channelDecisionManager"/></property>
|
|
||||||
<property name="filterInvocationDefinitionSource">
|
|
||||||
<value><![CDATA[
|
|
||||||
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
|
||||||
\A/secure/.*\Z=REQUIRES_SECURE_CHANNEL
|
|
||||||
\A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
|
|
||||||
\A/j_spring_security_check.*\Z=REQUIRES_SECURE_CHANNEL
|
|
||||||
\A.*\Z=REQUIRES_INSECURE_CHANNEL
|
|
||||||
]]></value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="channelDecisionManager" class="org.springframework.security.securechannel.ChannelDecisionManagerImpl">
|
|
||||||
<property name="channelProcessors">
|
|
||||||
<list>
|
|
||||||
<ref local="secureChannelProcessor"/>
|
|
||||||
<ref local="insecureChannelProcessor"/>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="secureChannelProcessor" class="org.springframework.security.securechannel.SecureChannelProcessor"/>
|
|
||||||
<bean id="insecureChannelProcessor" class="org.springframework.security.securechannel.InsecureChannelProcessor"/>
|
|
||||||
|
|
||||||
<!-- ===================== HTTP REQUEST SECURITY ==================== -->
|
|
||||||
|
|
||||||
<bean id="exceptionTranslationFilter" class="org.springframework.security.ui.ExceptionTranslationFilter">
|
<bean id="exceptionTranslationFilter" class="org.springframework.security.ui.ExceptionTranslationFilter">
|
||||||
<property name="authenticationEntryPoint"><ref local="authenticationProcessingFilterEntryPoint"/></property>
|
<property name="authenticationEntryPoint"><ref local="authenticationProcessingFilterEntryPoint"/></property>
|
||||||
<property name="accessDeniedHandler">
|
<property name="accessDeniedHandler">
|
||||||
|
@ -169,18 +106,6 @@
|
||||||
<property name="forceHttps"><value>false</value></property>
|
<property name="forceHttps"><value>false</value></property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="httpRequestAccessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
|
|
||||||
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
|
|
||||||
<property name="decisionVoters">
|
|
||||||
<list>
|
|
||||||
<ref bean="roleVoter"/>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- Note the order that entries are placed against the objectDefinitionSource is critical.
|
|
||||||
The FilterSecurityInterceptor will work from the top of the list down to the FIRST pattern that matches the request URL.
|
|
||||||
Accordingly, you should place MOST SPECIFIC (ie a/b/c/d.*) expressions first, with LEAST SPECIFIC (ie a/.*) expressions last -->
|
|
||||||
<bean id="filterInvocationInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
|
<bean id="filterInvocationInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
|
||||||
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
|
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
|
||||||
<property name="accessDecisionManager"><ref local="httpRequestAccessDecisionManager"/></property>
|
<property name="accessDecisionManager"><ref local="httpRequestAccessDecisionManager"/></property>
|
||||||
|
@ -199,14 +124,44 @@
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<authentication-provider>
|
||||||
|
<password-encoder hash="md5"/>
|
||||||
|
<jdbc-user-service data-source="dataSource"/>
|
||||||
|
</authentication-provider>
|
||||||
|
<!--
|
||||||
|
<bean id="jdbcDaoImpl" class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">
|
||||||
|
<property name="dataSource" ref="dataSource"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="passwordEncoder" class="org.springframework.security.providers.encoding.Md5PasswordEncoder"/>
|
||||||
|
|
||||||
|
<bean id="daoAuthenticationProvider" class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
|
||||||
|
<property name="userDetailsService"><ref local="jdbcDaoImpl"/></property>
|
||||||
|
<property name="passwordEncoder"><ref local="passwordEncoder"/></property>
|
||||||
|
</bean>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Automatically receives AuthenticationEvent messages -->
|
||||||
|
<b:bean id="loggerListener" class="org.springframework.security.event.authentication.LoggerListener"/>
|
||||||
|
|
||||||
|
|
||||||
|
<b:bean id="httpRequestAccessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
|
||||||
|
<b:property name="allowIfAllAbstainDecisions" value="false" />
|
||||||
|
<b:property name="decisionVoters">
|
||||||
|
<b:list>
|
||||||
|
<b:ref bean="roleVoter"/>
|
||||||
|
</b:list>
|
||||||
|
</b:property>
|
||||||
|
</b:bean>
|
||||||
|
|
||||||
|
|
||||||
<!-- Filter used to switch the user context. Note: the switch and exit url must be secured
|
<!-- Filter used to switch the user context. Note: the switch and exit url must be secured
|
||||||
based on the role granted the ability to 'switch' to another user -->
|
based on the role granted the ability to 'switch' to another user -->
|
||||||
<!-- In this example 'rod' has ROLE_SUPERVISOR that can switch to regular ROLE_USER(s) -->
|
<!-- In this example 'rod' has ROLE_SUPERVISOR that can switch to regular ROLE_USER(s) -->
|
||||||
<bean id="switchUserProcessingFilter" class="org.springframework.security.ui.switchuser.SwitchUserProcessingFilter">
|
<b:bean id="switchUserProcessingFilter" class="org.springframework.security.ui.switchuser.SwitchUserProcessingFilter" autowire="byType">
|
||||||
<property name="userDetailsService" ref="jdbcDaoImpl" />
|
<b:property name="targetUrl" value="/spring-security-sample-contacts-filter/secure/index.htm"/>
|
||||||
<property name="switchUserUrl"><value>/j_spring_security_switch_user</value></property>
|
</b:bean>
|
||||||
<property name="exitUserUrl"><value>/j_spring_security_exit_user</value></property>
|
|
||||||
<property name="targetUrl"><value>/spring-security-sample-contacts-filter/secure/index.htm</value></property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</beans>
|
</b:beans>
|
||||||
|
|
Loading…
Reference in New Issue