如何评估Spring EL中的Spring EL

时间:2013-09-23 11:36:35

标签: spring spring-el

(对不起,如果这是重复的,但问题是搜索引擎不友好。)

我想知道如何评估EL中的Spring EL(包含所有函数,变量,上下文等)。

具体来说,我想动态评估从@PreAuthorize中硬编码EL内的数据库实体加载的Spring Security表达式(只是EL加上一些函数和上下文)。

即。类似于@PreAuthorize("eval(argument.securityExpr)")

2 个答案:

答案 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>