2

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

我想知道如何在 EL 中评估 Spring EL(所有函数、变量、上下文等都通过)。

具体来说,我想动态评估从@PreAuthorize.

即类似的东西@PreAuthorize("eval(argument.securityExpr)")

4

2 回答 2

2

您可以扩展 Springs MethodSecurityExpressionRoot(并在您自己的 MethodSecurityExpressionHandler 中创建它)并添加一个除字符串之外的 eval 方法,并让 SpringExpressionParser 评估字符串。应该管用...

编辑:

一小段代码:

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!可能是安全漏洞。

于 2013-11-08T12:28:51.957 回答
0

如果您使用 simpleparametername discover with@来评估权限,您几乎可以做任何您想做的事情,而无需启用调试模式。

@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>
于 2013-11-08T13:03:50.410 回答