春季角色扮演

时间:2019-07-09 08:09:08

标签: spring expression spring-el

我有一个自定义要求,我想根据某些角色决定是否可以访问API。我正在使用Spring框架。 我想支持这样的事情:

(R1 || R2) && (R3 || R4)  
(R1) || (R2 && R3) 

其中R代表一个角色。 ||&&是分别表示orand的逻辑运算符。 该表达式应针对数组求值。 因此,如果数组为[R2,R4],则第一个表达式的值为true,第二个表达式的值为false。

我使用SPEL找到了类似的东西,但不是R,它可以是 customer employee 等任何字符串,它们使用的是布尔表达式值,例如true6 == 6

2 个答案:

答案 0 :(得分:2)

您可以将基于角色的方法安全性用于SpEL。

@PreAuthorize("hasRole('ROLE_A') or hasRole('ROLE_B')")
public void yourMethod() {
    // ...
}

答案 1 :(得分:0)

我使用以下方法解决了上述问题:

  1. 我使用了Spring提供的SpEL。
  2. SpEL支持属性替换。

替换代码:

Inventor tesla = new Inventor("Nikola Tesla");
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("name == Nikola Tesla");
String name = (String) exp.getValue(tesla);

此处,name属性将由Nikola Tesla替换。 每次对表达式求值时,name属性具有不同的值时,应使用此方法。 如果name属性的值每次都相同,请考虑使用EvaluationContext

现在谈论布尔表达式,您将不得不强制用值替代属性,因为在上面的示例中,属性name可以将null作为默认值,但是字符串角色不能取truefalse而不替换。
 并且假设SpEL包含一些我不知道的角色,我将无法用truefalse替换它们。为了解决这个问题,我使用了类似于@PreAuthorize的方法,它具有方法hasRole()

参考代码:

String roles =  "(hasRole('admin') or hasRole('superAdmin')) and hasRole('modifier')"
Expression roleExpression = parser.parseExpression(roles);
StandardEvaluationContext roleContext = new StandardEvaluationContext(new SpelHelper());
roleContext.addPropertyAccessor(new MapAccessor()); // this line might be useless
Boolean hasCorrectRole = roleExpression.getValue(roleContext, Boolean.class);


class SpelHelper {
     public boolean hasRole(String role) {
          // some logic like current user roles have the role passed as argument
          return true;
     }
}

完整文档位于: https://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/expressions.html

另外,请参考Boolean Expression Evaluation in Java
该答案建议使用JEXL,并且该答案将使您很清楚该如何替换属性。

相关问题