Reputation: 1149
I need to evaluate a dynamic user-generated expression based on a bean using the Spring Expression Language, but I wish to limit the fields they can use via an annotation. For example, if I had the below class I would like to be able to evaluate the expression field1 + field2
, but if I tried to evaluate field1 + field3
this would lead to an exception being generated.
Is this possible? Is there a different way to limit the scope of the expression?
public class Foo {
@AllowedField
private int field1;
@AllowedField
private int field2;
private int field3;
}
Upvotes: 2
Views: 1335
Reputation: 1149
Basically, this is what you need to do
Extend StandardEvaluationContext
to return your own PropertyAccessor
:
public class SecureEvaluationContext extends StandardEvaluationContext {
@Override
public List<PropertyAccessor> getPropertyAccessors() {
return Arrays.asList(new SecurePropertyAccessor());
}
}
Extend ReflectivePropertyAccessor
and implemet your own canRead
:
public class SecurePropertyAccessor extends ReflectivePropertyAccessor {
@Override
public boolean canRead(EvaluationContext context, Object target, String name) {
boolean canRead = // Add your own logic as needed
return canRead;
}
}
Evaluate with:
Expression expression = parser.parseExpression("field1 + field2");
EvaluationContext evaluationContext = new SecureEvaluationContext();
Double value = expression.getValue(evaluationContext, new ControlElement(), Double.class);
Upvotes: 4