У меня есть контроллер с операциями 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, если это необходимо.
@chrylis Нет. Spring выдает ошибку EL1008E: Property or field 'userId' cannot be found on object of type 'org.springframework.security.access.expression.method.MethodSecurityExpressionRoot' - maybe not public or not valid?




Здесь должны быть полезны документы Spring. https://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html
Вы можете получить доступ к принципалу или объекту аутентификации в выражении, а также к аргументам метода. Итак, у вас есть несколько вариантов, один из которых может быть примерно таким:
@PreAuthorize("hasRole('ROLE_ADMIN) or #authUser.id == #userId")
Это сработало. Волшебный # с обеих сторон мне помог. Спасибо.
Вы пробовали просто
or authUser.getId() == userId(или, проще говоря,authUser.id)? Он должен работать как есть.