🔥 Spring Security: как работает @PreAuthorize и зачем он нужен
В продакшн-коде часто возникает задача ограничить доступ к методам сервиса или контроллера. Делать это вручную — значит плодить дублирование и путать бизнес-логику с проверками. Для этого в Spring Security есть аннотация @PreAuthorize.
🔵 Как это работает
1. Аннотация вешается на метод (контроллер или сервис).
2. При вызове метода Spring Security перехватывает обращение и проверяет условие, указанное в аннотации.
3. Условие описывается на языке SpEL (Spring Expression Language), где доступно:
▪️ authentication — текущий объект аутентификации;
▪️ principal — данные текущего пользователя;
▪️ #id, #dto и т.д. — аргументы метода, к которым можно обратиться напрямую.
Пример:
→ метод вызовется только для пользователей с ролью ADMIN.
🔵 Что можно писать внутри
— Проверка ролей и прав
— Собственные условия
→ Здесь доступ только к своему профилю.
— Комбинации условий
Логика пишется прямо в SpEL:
— Сервисы внутри выражений
В выражение можно подключать свои бины:
→ бин reviewSecurity должен быть в контексте Spring и возвращать true/false.
🔵 Зачем это нужно
— Не надо вручную писать проверки в каждом методе.
— Авторизация централизована и читается прямо на уровне API.
— Условия можно вынести в отдельный сервис, чтобы не захламлять аннотацию.
👉 В итоге @PreAuthorize — это не только про роли, а про гибкий DSL проверки доступа, который можно расширять под проект: от банальной проверки ролей до бизнес-логики уровня "пользователь может редактировать только свои документы, если они ещё не опубликованы".
🐸 Библиотека джависта
#Enterprise
В продакшн-коде часто возникает задача ограничить доступ к методам сервиса или контроллера. Делать это вручную — значит плодить дублирование и путать бизнес-логику с проверками. Для этого в Spring Security есть аннотация @PreAuthorize.
1. Аннотация вешается на метод (контроллер или сервис).
2. При вызове метода Spring Security перехватывает обращение и проверяет условие, указанное в аннотации.
3. Условие описывается на языке SpEL (Spring Expression Language), где доступно:
▪️ authentication — текущий объект аутентификации;
▪️ principal — данные текущего пользователя;
▪️ #id, #dto и т.д. — аргументы метода, к которым можно обратиться напрямую.
Пример:
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long id) { ... }
→ метод вызовется только для пользователей с ролью ADMIN.
— Проверка ролей и прав
hasRole('USER'), hasAnyRole('ADMIN','MODERATOR')
hasAuthority('SCOPE_read') (актуально при работе с OAuth2)
— Собственные условия
@PreAuthorize("#id == authentication.principal.id")
public UserProfile getProfile(Long id) { ... }
→ Здесь доступ только к своему профилю.
— Комбинации условий
Логика пишется прямо в SpEL:
@PreAuthorize("hasRole('ADMIN') or @securityService.isOwner(#docId)")
public Document update(Long docId) { ... }
— Сервисы внутри выражений
В выражение можно подключать свои бины:
@PreAuthorize("@reviewSecurity.isOwner(#id, authentication)")
public Review update(Long id) { ... }
→ бин reviewSecurity должен быть в контексте Spring и возвращать true/false.
— Не надо вручную писать проверки в каждом методе.
— Авторизация централизована и читается прямо на уровне API.
— Условия можно вынести в отдельный сервис, чтобы не захламлять аннотацию.
👉 В итоге @PreAuthorize — это не только про роли, а про гибкий DSL проверки доступа, который можно расширять под проект: от банальной проверки ролей до бизнес-логики уровня "пользователь может редактировать только свои документы, если они ещё не опубликованы".
#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍3🔥1