Spring Spel для ролей

У меня есть индивидуальное требование, в котором я хочу решить, можно ли получить доступ к API в зависимости от определенных ролей. Я использую Spring framework. Я хочу поддержать что-то вроде этого:

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

где R представляет роль. || и && - логические операторы, обозначающие соответственно or и and. Это выражение следует сравнивать с входным массивом ролей. Итак, если входным массивом является [R2, R4], тогда первое выражение оценивается как истинное, а второе выражение оценивается как ложное.

Я нашел нечто подобное с помощью SPEL, но вместо R, который может быть любой строкой, например customer, employee и т. Д., Они используют значение логических выражений, например true или 6 == 6 и т. Д.


person rohanagarwal    schedule 09.07.2019    source источник


Ответы (2)


Вы можете использовать метод безопасности на основе ролей с SpEL.

@PreAuthorize("hasRole('ROLE_A') or hasRole('ROLE_B')")
public void yourMethod() {
    // ...
}
person Ugur Artun    schedule 09.07.2019
comment
У меня есть индивидуальные требования, не могу пройти предварительную авторизацию - person rohanagarwal; 09.07.2019

Я решил вышеуказанную проблему, используя следующее:

  1. Я использовал SpEL, предоставленный Spring.
  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 имеет разное значение при каждой оценке выражения. Если значение свойства 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

Также см. Оценка логического выражения в Java
В этом ответе предлагается использовать JEXL и ответ даст вам четкое представление о том, что делать, чтобы заменить свойства.

person rohanagarwal    schedule 09.07.2019