我有一个自定义要求,我想根据某些角色决定是否可以访问API。我正在使用Spring框架。 我想支持这样的事情:
(R1 || R2) && (R3 || R4)
(R1) || (R2 && R3)
其中R
代表一个角色。 ||
和&&
是分别表示or
和and
的逻辑运算符。
该表达式应针对数组求值。
因此,如果数组为[R2,R4],则第一个表达式的值为true,第二个表达式的值为false。
我使用SPEL找到了类似的东西,但不是R
,它可以是 customer , employee 等任何字符串,它们使用的是布尔表达式值,例如true
或6 == 6
等
答案 0 :(得分:2)
您可以将基于角色的方法安全性用于SpEL。
@PreAuthorize("hasRole('ROLE_A') or hasRole('ROLE_B')")
public void yourMethod() {
// ...
}
答案 1 :(得分:0)
我使用以下方法解决了上述问题:
替换代码:
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
作为默认值,但是字符串角色不能取true
或false
而不替换。
并且假设SpEL包含一些我不知道的角色,我将无法用true
和false
替换它们。为了解决这个问题,我使用了类似于@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,并且该答案将使您很清楚该如何替换属性。