(对不起,如果这是重复的,但问题是搜索引擎不友好。)
我想知道如何评估EL中的Spring EL(包含所有函数,变量,上下文等)。
具体来说,我想动态评估从@PreAuthorize
中硬编码EL内的数据库实体加载的Spring Security表达式(只是EL加上一些函数和上下文)。
即。类似于@PreAuthorize("eval(argument.securityExpr)")
。
答案 0 :(得分:2)
您可以扩展Springs MethodSecurityExpressionRoot(并在您自己的MethodSecurityExpressionHandler中创建它)并添加一个除了String之外的eval方法,并让SpringExpressionParser评估String。应该工作......
编辑:
一点代码:
public class MySpringSecurityRoot extends MethodSecurityExpressionRoot {
private MyMethodSecurityExpressionHandler handler; // to be injected in the handler
public boolean eval(String expression) {
Expression expression = handler.getExpressionParser().parseExpression(expression);
return ExpressionUtils.evaluateAsBoolean(
handler.getExpressionParser().parseExpression(expression),
handler.createEvaluationContext(authentification, methodInvocation));
}
}
必须将您的处理程序设置为默认方法安全表达式处理程序:
<security:global-method-security pre-post-annotations="enabled">
<security:expression-handler ref="myHandler"/>
</security:global-method-security>
现在您的eval函数可以在每个方法安全表达式中访问
但是:您必须意识到描述您的安全规则的人可以访问当前Spring环境中的所有bean!可能是安全漏洞。
答案 1 :(得分:0)
如果您使用@
的简单参数发现来评估权限,您可以执行任何您想要的操作,而无需启用调试模式。
@PreAuthorize("@mySecurityService.hasPermission(#arg0)")
public String getSpecial(final String special) {
return "authorized";
}
mySecurityService可以是任何返回布尔值的bean /方法,其中为arg1连接了
public class SimpleParameterNameDiscoverer implements ParameterNameDiscoverer {
public String[] getParameterNames(Method m) {
return getParameterNames(m.getParameterTypes().length);
}
public String[] getParameterNames(Constructor c) {
return getParameterNames(c.getParameterTypes().length);
}
protected String[] getParameterNames(int length) {
String[] names = new String[length];
for (int i = 0; i < length; i++)
names[i] = "arg" + i;
return names;
}
}
和上下文:
<bean id="methodSecurityExpressionHandler"
class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<property name="parameterNameDiscoverer">
<bean class="your.path.SimpleParameterNameDiscoverer"/>
</property>