Skip to content

Instantly share code, notes, and snippets.

@nickspacek
Created August 13, 2012 12:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickspacek/3340059 to your computer and use it in GitHub Desktop.
Save nickspacek/3340059 to your computer and use it in GitHub Desktop.
Workaround for Spring Security 3.0.x lack of BeanResolver in EvaluationContext
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);
}
}
}
@virtualdogbert
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment