Spring 角色拼写
Spring Spel for roles
我有一个自定义要求,我想根据某些角色决定是否可以访问 API。我正在使用 Spring 框架。
我想支持这样的事情:
1. (R1 || R2) && (R3 || R4)
2. (R1) || (R2 && R3)
其中 R
代表一个角色。 ||
和 &&
是逻辑运算符,分别表示 or
和 and
。
该表达式应该针对输入的角色数组进行评估。
因此,如果输入数组是 [R2, R4],则第一个表达式的计算结果为真,第二个表达式的计算结果为假。
我使用 SPEL 发现了类似的东西,但不是 R
,它可以是任何字符串,例如 customer、employee 等,他们使用布尔表达式值,如 true
或 6 == 6
,等等
您可以在 SpEL 中使用基于角色的方法安全性。
@PreAuthorize("hasRole('ROLE_A') or hasRole('ROLE_B')")
public void yourMethod() {
// ...
}
我使用以下方法解决了上述问题:
- 我使用了 Spring 提供的 SpEL。
- 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
作为默认值,但是字符串角色不能在没有替换的情况下使用 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
This answer suggests using JEXL and the answer will give you a fair idea 如何替换属性。
我有一个自定义要求,我想根据某些角色决定是否可以访问 API。我正在使用 Spring 框架。 我想支持这样的事情:
1. (R1 || R2) && (R3 || R4)
2. (R1) || (R2 && R3)
其中 R
代表一个角色。 ||
和 &&
是逻辑运算符,分别表示 or
和 and
。
该表达式应该针对输入的角色数组进行评估。
因此,如果输入数组是 [R2, R4],则第一个表达式的计算结果为真,第二个表达式的计算结果为假。
我使用 SPEL 发现了类似的东西,但不是 R
,它可以是任何字符串,例如 customer、employee 等,他们使用布尔表达式值,如 true
或 6 == 6
,等等
您可以在 SpEL 中使用基于角色的方法安全性。
@PreAuthorize("hasRole('ROLE_A') or hasRole('ROLE_B')")
public void yourMethod() {
// ...
}
我使用以下方法解决了上述问题:
- 我使用了 Spring 提供的 SpEL。
- 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
作为默认值,但是字符串角色不能在没有替换的情况下使用 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
This answer suggests using JEXL and the answer will give you a fair idea 如何替换属性。