Spring 角色拼写

Spring Spel for roles

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

1. (R1 || R2) && (R3 || R4)  
2. (R1) || (R2 && R3) 

其中 R 代表一个角色。 ||&& 是逻辑运算符,分别表示 orand。 该表达式应该针对输入的角色数组进行评估。 因此,如果输入数组是 [R2, R4],则第一个表达式的计算结果为真,第二个表达式的计算结果为假。

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

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

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

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

  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 属性 将被尼古拉·特斯拉取代。 当每次计算表达式时名称 属性 具有不同的值时,应使用此选项。 如果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
This answer suggests using JEXL and the answer will give you a fair idea 如何替换属性。