Spring Spel для ролей - PullRequest
       26

Spring Spel для ролей

1 голос
/ 09 июля 2019

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

(R1 || R2) && (R3 || R4)  
(R1) || (R2 && R3) 

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

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

Ответы [ 2 ]

2 голосов
/ 09 июля 2019

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

@PreAuthorize("hasRole('ROLE_A') or hasRole('ROLE_B')")
public void yourMethod() {
    // ...
}
0 голосов
/ 09 июля 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, и ответ даст вам четкое представление о том, что делать для замены свойств.

...