Какие аннотации используются для ограничения доступа к контроллерам в Spring Security
Что проверяют
Знаете ли вы разницу между защитой по URL в SecurityFilterChain и защитой методов аннотациями, и помните ли, что аннотации без включения ничего не делают. Следом просят сравнить @Secured и @PreAuthorize или проверить, что пользователь редактирует только свои данные.
Как отвечать
Сначала механизм: аннотации обрабатывает method security, её включает @EnableMethodSecurity на конфигурации, на смену устаревшей @EnableGlobalMethodSecurity. Проверку выполняет AOP-прокси до или после вызова метода, при отказе летит AccessDeniedException, и клиент получает 403.
Сами аннотации:
@PreAuthorize: SpEL-выражение до вызова, включена по умолчанию. Умеет роли (hasRole('ADMIN')), права (hasAuthority('SCOPE_orders.read')), параметры метода (#id == authentication.principal.id) и вызов бина:@PreAuthorize("@access.canEdit(#id)");@PostAuthorize: проверка после вызова поreturnObject, например что возвращаемый документ принадлежит текущему пользователю;@PreFilterи@PostFilter: фильтруют входную или выходную коллекцию по выражению;@Secured: только список ролей, без выражений. Нужен@EnableMethodSecurity(securedEnabled = true);@RolesAllowed: стандартная аннотация JSR-250, в Spring Boot 3 из пакетаjakarta.annotation.security. Нуженjsr250Enabled = true.
Повторяющиеся выражения удобно завернуть в свою мета-аннотацию вроде @IsAdmin поверх @PreAuthorize. Грубые правила по путям (/admin/** только для администраторов) держат в SecurityFilterChain, а проверки владения данными в аннотациях на сервисах.
Где спотыкаются
Забывают @EnableMethodSecurity или флаги для @Secured и @RolesAllowed. Аннотации молча игнорируются, и эндпоинт открыт всем.
Путают роли и права. hasRole('ADMIN') ищет полномочие ROLE_ADMIN, и если в токене пришло просто ADMIN, проверка не пройдёт, здесь нужен hasAuthority.
Ставят аннотацию на приватный метод или вызывают защищённый метод из того же класса через this. Вызов идёт мимо прокси, и проверки нет.