Как реализовать сброс сессии или прав доступа для конкретного пользователя
Что проверяют
Понимаете ли вы, где живут сессия и права пользователя, и умеете ли завершить чужую сессию, а не свою. Следом почти всегда спрашивают, как это работает в кластере из нескольких инстансов и что делать при аутентификации на JWT.
Как отвечать
Разделите две задачи. Сброс сессии разлогинивает пользователя. Смена прав разлогина не требует, но в Spring Security роли лежат в Authentication внутри SecurityContext, который хранится в сессии, поэтому новые роли из базы не действуют до следующего входа.
Варианты по архитектуре:
- одна нода:
SessionRegistryплюсHttpSessionEventPublisher, затемgetAllSessions(principal, false)иexpireNow()для каждой. Сессия отклоняется при следующем запросе вConcurrentSessionFilter; - кластер: реестр в памяти видит только свою ноду, поэтому сессии выносят в Spring Session с Redis или JDBC.
FindByIndexNameSessionRepository.findByPrincipalName(username)вернёт сессии пользователя со всех нод, остаётся вызватьdeleteById; - JWT: токен без состояния не отозвать, поэтому access-токен живёт минуты, refresh-токены хранятся в базе и отзываются там. Для немедленной блокировки сверяют версию токенов пользователя или список отозванных
jtiв Redis; - внешний IdP: в Keycloak сессии пользователя завершаются через Admin API, приложения узнают об этом через back-channel logout.
Чтобы новые права применялись без выхода, полномочия можно перечитывать из базы на каждый запрос или с коротким TTL кеша. Цену в производительности стоит назвать.
И мелочь: в Spring Boot 3 сервлетный API живёт в jakarta.servlet, а не в javax.servlet.
Где спотыкаются
Вызывают session.invalidate() или SecurityContextLogoutHandler в админском эндпоинте. Оба работают с сессией текущего запроса и разлогинивают самого администратора, а не нужного пользователя.
Объявляют бин SessionRegistry и ждут, что он наполнится сам. Сессии туда попадают только при включённом maximumSessions(...), а без HttpSessionEventPublisher реестр не узнаёт об уничтоженных сессиях.
Считают, что удаление JWT на клиенте это отзыв. Украденный токен работает до истечения срока, если сервер ничего не проверяет.