Created
August 13, 2012 12:04
-
-
Save nickspacek/3340059 to your computer and use it in GitHub Desktop.
Workaround for Spring Security 3.0.x lack of BeanResolver in EvaluationContext
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SecuritySpelBeanResolverInjector implements BeanFactoryAware, BeanPostProcessor { | |
private BeanFactory factory; | |
@Override | |
public Object postProcessAfterInitialization(Object bean, String beanName) | |
throws BeansException { | |
if (bean instanceof ExpressionBasedPreInvocationAdvice) { | |
((ExpressionBasedPreInvocationAdvice) bean).setExpressionHandler(new CustomMethodSecurityExpressionHandler()); | |
} | |
return bean; | |
} | |
@Override | |
public Object postProcessBeforeInitialization(Object bean, String beanName) | |
throws BeansException { | |
return bean; | |
} | |
@Override | |
public void setBeanFactory(BeanFactory beanFactory) | |
throws BeansException { | |
this.factory = beanFactory; | |
} | |
private class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler { | |
public EvaluationContext createEvaluationContext(Authentication authentication, MethodInvocation mi) { | |
return new BeanResolverAwareEvaluationContext(super.createEvaluationContext(authentication, mi)); | |
} | |
} | |
private class BeanResolverAwareEvaluationContext implements EvaluationContext { | |
private EvaluationContext delegate; | |
private BeanResolver beanResolver; | |
public BeanResolverAwareEvaluationContext(EvaluationContext delegate) { | |
this.delegate = delegate; | |
beanResolver = new BeanFactoryResolver(factory); | |
} | |
public TypedValue getRootObject() { | |
return delegate.getRootObject(); | |
} | |
public List<ConstructorResolver> getConstructorResolvers() { | |
return delegate.getConstructorResolvers(); | |
} | |
public List<MethodResolver> getMethodResolvers() { | |
return delegate.getMethodResolvers(); | |
} | |
public List<PropertyAccessor> getPropertyAccessors() { | |
return delegate.getPropertyAccessors(); | |
} | |
public TypeLocator getTypeLocator() { | |
return delegate.getTypeLocator(); | |
} | |
public TypeConverter getTypeConverter() { | |
return delegate.getTypeConverter(); | |
} | |
public TypeComparator getTypeComparator() { | |
return delegate.getTypeComparator(); | |
} | |
public OperatorOverloader getOperatorOverloader() { | |
return delegate.getOperatorOverloader(); | |
} | |
public BeanResolver getBeanResolver() { | |
return beanResolver; | |
} | |
public void setVariable(String name, Object value) { | |
delegate.setVariable(name, value); | |
} | |
public Object lookupVariable(String name) { | |
return delegate.lookupVariable(name); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Found this off of stack overflow and it works great for adding the ability to call bean from spring security annotations. However I ran into an issue, if I use this, none of the variables from the method header are recognize:
@PreAuthorize("hasPermission(#id, 'com.company.platform.domain.Object', 'view')")
def getObjectt(id, user) {
in this case I would get an error saying that #id couldn't be found. Any Ideas on how I might overcome this. Also to give some context I'm running this from a grails application, using the spring security core and acl plug ins.