SEC-783: GlobalMethodSecurityBeanDefinitionParser should support AfterInvocationProviders
http://jira.springframework.org/browse/SEC-783. Added support for custom-after-invocation-provider
This commit is contained in:
parent
348d211b8c
commit
d3a0f05de9
|
@ -1,5 +1,7 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
|
||||
/**
|
||||
* Contains all the default Bean IDs created by the namespace support in Spring Security 2.
|
||||
* <p>
|
||||
|
@ -31,6 +33,7 @@ public abstract class BeanIds {
|
|||
public static final String CONCURRENT_SESSION_CONTROLLER = "_concurrentSessionController";
|
||||
public static final String ACCESS_MANAGER = "_accessManager";
|
||||
public static final String AUTHENTICATION_MANAGER = "_authenticationManager";
|
||||
public static final String AFTER_INVOCATION_MANAGER = "_afterInvocationManager";
|
||||
public static final String FORM_LOGIN_FILTER = "_formLoginFilter";
|
||||
public static final String FORM_LOGIN_ENTRY_POINT = "_formLoginEntryPoint";
|
||||
public static final String OPEN_ID_FILTER = "_openIDFilter";
|
||||
|
@ -50,6 +53,7 @@ public abstract class BeanIds {
|
|||
public static final String SECURITY_CONTEXT_HOLDER_AWARE_REQUEST_FILTER = "_securityContextHolderAwareRequestFilter";
|
||||
public static final String SESSION_FIXATION_PROTECTION_FILTER = "_sessionFixationProtectionFilter";
|
||||
public static final String METHOD_SECURITY_INTERCEPTOR = "_methodSecurityInterceptor";
|
||||
public static final String METHOD_SECURITY_INTERCEPTOR_POST_PROCESSOR = "_methodSecurityInterceptorPostProcessor";
|
||||
public static final String METHOD_DEFINITION_SOURCE_ADVISOR = "_methodDefinitionSourceAdvisor";
|
||||
public static final String PROTECT_POINTCUT_POST_PROCESSOR = "_protectPointcutPostProcessor";
|
||||
public static final String DELEGATING_METHOD_DEFINITION_SOURCE = "_delegatingMethodDefinitionSource";
|
||||
|
@ -62,4 +66,5 @@ public abstract class BeanIds {
|
|||
public static final String X509_AUTH_PROVIDER = "_x509AuthenitcationProvider";
|
||||
public static final String PRE_AUTH_ENTRY_POINT = "_preAuthenticatedProcessingFilterEntryPoint";
|
||||
public static final String REMEMBER_ME_SERVICES_INJECTION_POST_PROCESSOR = "_rememberMeServicesInjectionBeanPostProcessor";
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
|||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.security.afterinvocation.AfterInvocationProviderManager;
|
||||
import org.springframework.security.providers.ProviderManager;
|
||||
import org.springframework.security.userdetails.UserDetailsService;
|
||||
import org.springframework.security.vote.AffirmativeBased;
|
||||
|
@ -114,6 +115,23 @@ public abstract class ConfigUtils {
|
|||
return (ManagedList) authManager.getPropertyValues().getPropertyValue("providers").getValue();
|
||||
}
|
||||
|
||||
static ManagedList getRegisteredAfterInvocationProviders(ParserContext parserContext) {
|
||||
BeanDefinition manager = registerAfterInvocationProviderManagerIfNecessary(parserContext);
|
||||
return (ManagedList) manager.getPropertyValues().getPropertyValue("providers").getValue();
|
||||
}
|
||||
|
||||
private static BeanDefinition registerAfterInvocationProviderManagerIfNecessary(ParserContext parserContext) {
|
||||
if(parserContext.getRegistry().containsBeanDefinition(BeanIds.AFTER_INVOCATION_MANAGER)) {
|
||||
return parserContext.getRegistry().getBeanDefinition(BeanIds.AFTER_INVOCATION_MANAGER);
|
||||
}
|
||||
|
||||
BeanDefinition manager = new RootBeanDefinition(AfterInvocationProviderManager.class);
|
||||
manager.getPropertyValues().addPropertyValue("providers", new ManagedList());
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.AFTER_INVOCATION_MANAGER, manager);
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
private static void registerFilterChainPostProcessorIfNecessary(ParserContext pc) {
|
||||
if (pc.getRegistry().containsBeanDefinition(BeanIds.FILTER_CHAIN_POST_PROCESSOR)) {
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Adds the decorated {@link org.springframework.security.afterinvocation.AfterInvocationProvider} to the
|
||||
* AfterInvocationProviderManager's list.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 2.0
|
||||
*/
|
||||
public class CustomAfterInvocationProviderBeanDefinitionDecorator implements BeanDefinitionDecorator {
|
||||
|
||||
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder holder, ParserContext parserContext) {
|
||||
ConfigUtils.getRegisteredAfterInvocationProviders(parserContext).add(holder.getBeanDefinition());
|
||||
|
||||
return holder;
|
||||
}
|
||||
|
||||
}
|
|
@ -36,6 +36,7 @@ abstract class Elements {
|
|||
public static final String PORT_MAPPING = "port-mapping";
|
||||
public static final String CUSTOM_FILTER = "custom-filter";
|
||||
public static final String CUSTOM_AUTH_PROVIDER = "custom-authentication-provider";
|
||||
public static final String CUSTOM_AFTER_INVOCATION_PROVIDER = "custom-after-invocation-provider";
|
||||
public static final String X509 = "x509";
|
||||
public static final String FILTER_INVOCATION_DEFINITION_SOURCE = "filter-invocation-definition-source";
|
||||
public static final String LDAP_PASSWORD_COMPARE = "password-compare";
|
||||
|
|
|
@ -168,6 +168,9 @@ class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
|||
interceptor.getPropertyValues().addPropertyValue("objectDefinitionSource", new RuntimeBeanReference(BeanIds.DELEGATING_METHOD_DEFINITION_SOURCE));
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_SECURITY_INTERCEPTOR, interceptor);
|
||||
parserContext.registerComponent(new BeanComponentDefinition(interceptor, BeanIds.METHOD_SECURITY_INTERCEPTOR));
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_SECURITY_INTERCEPTOR_POST_PROCESSOR,
|
||||
new RootBeanDefinition(MethodSecurityInterceptorPostProcessor.class));
|
||||
}
|
||||
|
||||
private void registerAdvisor(ParserContext parserContext, Object source) {
|
||||
|
@ -179,5 +182,4 @@ class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
|||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_DEFINITION_SOURCE_ADVISOR, advisor);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.security.AfterInvocationManager;
|
||||
import org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor;
|
||||
|
||||
/**
|
||||
* BeanPostProcessor which sets the AfterInvocationManager on the default MethodSecurityInterceptor,
|
||||
* if one has been configured.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public class MethodSecurityInterceptorPostProcessor implements BeanPostProcessor, BeanFactoryAware{
|
||||
private Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
if(!beanName.equals(BeanIds.METHOD_SECURITY_INTERCEPTOR)) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
MethodSecurityInterceptor interceptor = (MethodSecurityInterceptor) bean;
|
||||
|
||||
if (beanFactory.containsBean(BeanIds.AFTER_INVOCATION_MANAGER)) {
|
||||
logger.debug("Setting AfterInvocationManaer on MethodSecurityInterceptor");
|
||||
interceptor.setAfterInvocationManager((AfterInvocationManager)
|
||||
beanFactory.getBean(BeanIds.AFTER_INVOCATION_MANAGER));
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
}
|
|
@ -30,5 +30,6 @@ public class SecurityNamespaceHandler extends NamespaceHandlerSupport {
|
|||
registerBeanDefinitionDecorator(Elements.FILTER_CHAIN_MAP, new FilterChainMapBeanDefinitionDecorator());
|
||||
registerBeanDefinitionDecorator(Elements.CUSTOM_FILTER, new OrderedFilterBeanDefinitionDecorator());
|
||||
registerBeanDefinitionDecorator(Elements.CUSTOM_AUTH_PROVIDER, new CustomAuthenticationProviderBeanDefinitionDecorator());
|
||||
registerBeanDefinitionDecorator(Elements.CUSTOM_AFTER_INVOCATION_PROVIDER, new CustomAfterInvocationProviderBeanDefinitionDecorator());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.AbstractXmlApplicationContext;
|
||||
import org.springframework.security.afterinvocation.AfterInvocationProviderManager;
|
||||
import org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor;
|
||||
import org.springframework.security.util.InMemoryXmlApplicationContext;
|
||||
|
||||
public class CustomAfterInvocationProviderBeanDefinitionDecoratorTests {
|
||||
private AbstractXmlApplicationContext appContext;
|
||||
|
||||
@After
|
||||
public void closeAppContext() {
|
||||
if (appContext != null) {
|
||||
appContext.close();
|
||||
appContext = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customAuthenticationProviderIsAddedToInterceptor() {
|
||||
setContext(
|
||||
"<global-method-security />" +
|
||||
"<b:bean id='aip' class='org.springframework.security.config.MockAfterInvocationProvider'>" +
|
||||
" <custom-after-invocation-provider />" +
|
||||
"</b:bean>" +
|
||||
HttpSecurityBeanDefinitionParserTests.AUTH_PROVIDER_XML
|
||||
);
|
||||
|
||||
MethodSecurityInterceptor msi = (MethodSecurityInterceptor) appContext.getBean(BeanIds.METHOD_SECURITY_INTERCEPTOR);
|
||||
AfterInvocationProviderManager apm = (AfterInvocationProviderManager) msi.getAfterInvocationManager();
|
||||
assertNotNull(apm);
|
||||
assertEquals(1, apm.getProviders().size());
|
||||
assertTrue(apm.getProviders().get(0) instanceof MockAfterInvocationProvider);
|
||||
}
|
||||
|
||||
private void setContext(String context) {
|
||||
appContext = new InMemoryXmlApplicationContext(context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.security.AccessDeniedException;
|
||||
import org.springframework.security.Authentication;
|
||||
import org.springframework.security.ConfigAttribute;
|
||||
import org.springframework.security.ConfigAttributeDefinition;
|
||||
import org.springframework.security.afterinvocation.AfterInvocationProvider;
|
||||
|
||||
public class MockAfterInvocationProvider implements AfterInvocationProvider {
|
||||
|
||||
public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config, Object returnedObject)
|
||||
throws AccessDeniedException {
|
||||
return returnedObject;
|
||||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supports(Class clazz) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue