Как закрыть эндпоинты в Spring Security для проверки прав или ролей пользователя
Что проверяют
Знаете ли вы актуальную конфигурацию Spring Security и разницу между защитой по URL и на уровне методов. Следом обычно спрашивают, чем hasRole отличается от hasAuthority и как роли попадают в приложение из JWT.
Как отвечать
С Spring Security 6 (Spring Boot 3) WebSecurityConfigurerAdapter удалён, правила задаются бином SecurityFilterChain:
- правила по URL:
http.authorizeHttpRequests(a -> a.requestMatchers("/admin/**").hasRole("ADMIN").anyRequest().authenticated()). Правила проверяются сверху вниз, срабатывает первое совпавшее, поэтому частные пути идут раньше общих, аanyRequest()последним; - роль и полномочие:
hasRole("ADMIN")ищет authorityROLE_ADMIN, префикс добавляется сам.hasAuthority("orders:read")сравнивает строку целиком и подходит для тонких прав; - методы:
@EnableMethodSecurityна конфигурации и@PreAuthorize("hasRole('ADMIN')")над методом сервиса. Выражение видит аргументы, так что можно проверить владельца ресурса, а не только роль; - JWT:
oauth2ResourceServer(o -> o.jwt(Customizer.withDefaults())). Scope из токена превращаются в authorities с префиксомSCOPE_, а роли из Keycloak или своего claim достают через собственныйJwtAuthenticationConverter; - коды ответа: без аутентификации 401, с аутентификацией, но без прав 403.
Проверку закрепляют тестами на MockMvc с @WithMockUser(roles = "ADMIN"). В Spring Security 7 остался только лямбда-DSL, цепочки через and() больше не работают.
Где спотыкаются
Пишут по старой памяти antMatchers и extends WebSecurityConfigurerAdapter. Оба исчезли в шестой версии, и интервьюер сразу поймёт, что опыт давний.
Передают hasRole("ROLE_ADMIN") в правилах по URL. Spring сам добавляет префикс и на такую строку бросает исключение при старте.
Вызывают метод с @PreAuthorize из того же класса. Проверка работает через прокси, и при вызове через this она просто не выполняется.