Spring-Boot @PreAuthorize разрешает операцию только для администратора или если идентификатор аутентифицированного пользователя совпадает с идентификатором параметра пути

У меня есть контроллер с операциями User CRUD.

@Controller
public class UserController {

  // @TODO need to check whether userId == authUser.id or authUser is admin??
  //
  @PreAuthorize("hasRole('ROLE_ADMIN) or ...???...")
  @PostMapping("/user/{id}/edit")
  public boolean editUser(@PathVariable("id") long userId,
                          @RequestBody User newUserObj,
                          @CurrentUser authUser) {
     // I don't like to always call a helper function from here
     // check(authUser.getId() == userId);

     return userService.edit(userId, newUserObj);
  }

 // ... rest of the methods

}

Эта операция разрешена только администратору или самому пользователю. Ни один пользователь не может редактировать профили других пользователей.

Я пробовал @PreAuthorize("hasRole('ROLE_ADMIN')), он работает только для пользователя с правами администратора, но я хочу проверить, является ли аутентифицированный пользователь тем же пользователем, что указан параметром userId (authUser.getId() == userId). Как я могу определить это выражение внутри аннотации? Возможно ли это без написания вспомогательной функции.

У меня также есть текущий аутентифицированный пользователь, введенный в метод контроллера с использованием аннотации @CurrentUser, если это необходимо.

Вы пробовали просто or authUser.getId() == userId (или, проще говоря, authUser.id)? Он должен работать как есть.

chrylis -cautiouslyoptimistic- 12.01.2019 04:41

@chrylis Нет. Spring выдает ошибку EL1008E: Property or field 'userId' cannot be found on object of type 'org.springframework.security.access.expression.method.Metho‌​dSecurityExpressionR‌​oot' - maybe not public or not valid?

isuru89 12.01.2019 05:21
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
8
2
3 956
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь должны быть полезны документы Spring. https://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html

Вы можете получить доступ к принципалу или объекту аутентификации в выражении, а также к аргументам метода. Итак, у вас есть несколько вариантов, один из которых может быть примерно таким:

@PreAuthorize("hasRole('ROLE_ADMIN) or #authUser.id == #userId")

Это сработало. Волшебный # с обеих сторон мне помог. Спасибо.

isuru89 12.01.2019 05:24

Другие вопросы по теме