@ -15,6 +15,9 @@
package org.springframework.security.access.intercept.aopalliance ;
package org.springframework.security.access.intercept.aopalliance ;
import java.io.IOException ;
import java.io.ObjectInputStream ;
import java.io.Serializable ;
import java.lang.reflect.AccessibleObject ;
import java.lang.reflect.AccessibleObject ;
import java.lang.reflect.Method ;
import java.lang.reflect.Method ;
@ -31,7 +34,7 @@ import org.springframework.util.Assert;
/ * *
/ * *
* Advisor driven by a { @link MethodSecurityMetadataSource } , used to exclude a { @link MethodSecurityInterceptor } from
* Advisor driven by a { @link MethodSecurityMetadataSource } , used to exclude a { @link MethodSecurityInterceptor } from
* public ( ie non - secure ) methods .
* public ( non - secure ) methods .
* < p >
* < p >
* Because the AOP framework caches advice calculations , this is normally faster than just letting the
* Because the AOP framework caches advice calculations , this is normally faster than just letting the
* < code > MethodSecurityInterceptor < / code > run and find out itself that it has no work to do .
* < code > MethodSecurityInterceptor < / code > run and find out itself that it has no work to do .
@ -44,23 +47,25 @@ import org.springframework.util.Assert;
* Based on Spring ' s TransactionAttributeSourceAdvisor .
* Based on Spring ' s TransactionAttributeSourceAdvisor .
*
*
* @author Ben Alex
* @author Ben Alex
* @author Luke Taylor
* /
* /
public class MethodSecurityMetadataSourceAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
public class MethodSecurityMetadataSourceAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
//~ Instance fields ================================================================================================
//~ Instance fields ================================================================================================
private MethodSecurityMetadataSource attributeSource ;
private transient MethodSecurityMetadataSource attributeSource ;
private MethodSecurityInterceptor interceptor ;
private transient MethodSecurityInterceptor interceptor ;
private Pointcut pointcut = new MethodSecurityMetadataSourcePointcut ( ) ;
private final Pointcut pointcut = new MethodSecurityMetadataSourcePointcut ( ) ;
private BeanFactory beanFactory ;
private BeanFactory beanFactory ;
private String adviceBeanName ;
private String adviceBeanName ;
private final Object adviceMonitor = new Object ( ) ;
private String metadataSourceBeanName ;
private final Serializable adviceMonitor = new Serializable ( ) { } ;
//~ Constructors ===================================================================================================
//~ Constructors ===================================================================================================
/ * *
/ * *
* @deprecated use the decoupled approach instead
* @deprecated use the decoupled approach instead
* /
* /
public MethodSecurityMetadataSourceAdvisor ( MethodSecurityInterceptor advice ) {
MethodSecurityMetadataSourceAdvisor ( MethodSecurityInterceptor advice ) {
Assert . notNull ( advice . getSecurityMetadataSource ( ) , "Cannot construct a MethodSecurityMetadataSourceAdvisor using a " +
Assert . notNull ( advice . getSecurityMetadataSource ( ) , "Cannot construct a MethodSecurityMetadataSourceAdvisor using a " +
"MethodSecurityInterceptor that has no SecurityMetadataSource configured" ) ;
"MethodSecurityInterceptor that has no SecurityMetadataSource configured" ) ;
@ -71,21 +76,22 @@ public class MethodSecurityMetadataSourceAdvisor extends AbstractPointcutAdvisor
/ * *
/ * *
* Alternative constructor for situations where we want the advisor decoupled from the advice . Instead the advice
* Alternative constructor for situations where we want the advisor decoupled from the advice . Instead the advice
* bean name should be set . This prevents eager instantiation of the interceptor
* bean name should be set . This prevents eager instantiation of the interceptor
* ( and hence the AuthenticationManager ) . See SEC - 773 , for example .
* ( and hence the AuthenticationManager ) . See SEC - 773 , for example . The metadataSourceBeanName is used rather than
* < p >
* a direct reference to support serialization via a bean factory lookup .
* This is essentially the approach taken by subclasses of Spring ' s { @code AbstractBeanFactoryPointcutAdvisor } ,
* which this class should extend in future . The original hierarchy and constructor have been retained for backwards
* compatibility .
*
*
* @param adviceBeanName name of the MethodSecurityInterceptor bean
* @param adviceBeanName name of the MethodSecurityInterceptor bean
* @param attributeSource the attribute source ( should be the same as the one used on the interceptor )
* @param attributeSource the SecurityMetadataSource ( should be the same as the one used on the interceptor )
* @param attributeSourceBeanName the bean name of the attributeSource ( required for serialization )
* /
* /
public MethodSecurityMetadataSourceAdvisor ( String adviceBeanName , MethodSecurityMetadataSource attributeSource ) {
public MethodSecurityMetadataSourceAdvisor ( String adviceBeanName , MethodSecurityMetadataSource attributeSource ,
String attributeSourceBeanName ) {
Assert . notNull ( adviceBeanName , "The adviceBeanName cannot be null" ) ;
Assert . notNull ( adviceBeanName , "The adviceBeanName cannot be null" ) ;
Assert . notNull ( attributeSource , "The attributeSource cannot be null" ) ;
Assert . notNull ( attributeSource , "The attributeSource cannot be null" ) ;
Assert . notNull ( attributeSourceBeanName , "The attributeSourceBeanName cannot be null" ) ;
this . adviceBeanName = adviceBeanName ;
this . adviceBeanName = adviceBeanName ;
this . attributeSource = attributeSource ;
this . attributeSource = attributeSource ;
this . metadataSourceBeanName = attributeSourceBeanName ;
}
}
//~ Methods ========================================================================================================
//~ Methods ========================================================================================================
@ -99,8 +105,7 @@ public class MethodSecurityMetadataSourceAdvisor extends AbstractPointcutAdvisor
if ( interceptor = = null ) {
if ( interceptor = = null ) {
Assert . notNull ( adviceBeanName , "'adviceBeanName' must be set for use with bean factory lookup." ) ;
Assert . notNull ( adviceBeanName , "'adviceBeanName' must be set for use with bean factory lookup." ) ;
Assert . state ( beanFactory ! = null , "BeanFactory must be set to resolve 'adviceBeanName'" ) ;
Assert . state ( beanFactory ! = null , "BeanFactory must be set to resolve 'adviceBeanName'" ) ;
interceptor = ( MethodSecurityInterceptor )
interceptor = beanFactory . getBean ( this . adviceBeanName , MethodSecurityInterceptor . class ) ;
beanFactory . getBean ( this . adviceBeanName , MethodSecurityInterceptor . class ) ;
}
}
return interceptor ;
return interceptor ;
}
}
@ -110,9 +115,15 @@ public class MethodSecurityMetadataSourceAdvisor extends AbstractPointcutAdvisor
this . beanFactory = beanFactory ;
this . beanFactory = beanFactory ;
}
}
private void readObject ( ObjectInputStream ois ) throws IOException , ClassNotFoundException {
ois . defaultReadObject ( ) ;
attributeSource = beanFactory . getBean ( metadataSourceBeanName , MethodSecurityMetadataSource . class ) ;
}
//~ Inner Classes ==================================================================================================
//~ Inner Classes ==================================================================================================
class MethodSecurityMetadataSourcePointcut extends StaticMethodMatcherPointcut {
class MethodSecurityMetadataSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
@SuppressWarnings ( "unchecked" )
@SuppressWarnings ( "unchecked" )
public boolean matches ( Method m , Class targetClass ) {
public boolean matches ( Method m , Class targetClass ) {
return attributeSource . getAttributes ( m , targetClass ) ! = null ;
return attributeSource . getAttributes ( m , targetClass ) ! = null ;