【问题标题】:Spring Spel for roles角色的 Spring Spel
【发布时间】:2019-07-09 08:09:08
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: spring expression spring-el


    【解决方案1】:

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

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

    【讨论】:

    • 我有自定义需求,不能使用预授权
    【解决方案2】:

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

    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,答案会让您大致了解如何替换属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 2018-03-28
      • 1970-01-01
      • 2014-12-26
      相关资源
      最近更新 更多