Как различали запросы разных пользователей
Что проверяют
Понимаете ли вы, как в Java-бэкенде запрос связывается с пользователем и где эта связь живёт во время обработки. Вопрос про опыт, так что нужен ваш проект. Следом почти всегда спрашивают, что станет с контекстом безопасности в @Async и как держать сессии на нескольких инстансах.
Как отвечать
Опишите цепочку в вашем сервисе:
- сессия: сервлет-контейнер выдаёт cookie
JSESSIONID, по ней находитсяHttpSession. При нескольких инстансах сессии выносят в Redis через Spring Session, иначе приходится включать sticky sessions на балансировщике; - токен: для REST обычно JWT в заголовке
Authorization: Bearer. В Spring Security этоoauth2ResourceServerсjwt(), подпись проверяется по ключам JWKS провайдера вроде Keycloak; - где живёт пользователь: фильтры
SecurityFilterChainкладутAuthenticationвSecurityContextHolder, а в контроллере его достают через@AuthenticationPrincipal.
Важная деталь: по умолчанию SecurityContextHolder хранит контекст в ThreadLocal. Пока запрос обрабатывает один поток, всё работает. В @Async или CompletableFuture.supplyAsync контекст теряется, и его передают через DelegatingSecurityContextExecutor или аналогичную обёртку.
Для разбора логов добавьте идентификатор запроса: OncePerRequestFilter берёт X-Request-ID или генерирует UUID и кладёт в MDC, а шаблон Logback выводит его в каждой строке. В Spring Boot с Micrometer Tracing рядом появляются traceId и spanId.
Если в проекте это настраивал не вы, скажите прямо и объясните, как устроено в вашем пет-проекте или как вы бы это сделали. Цифры и детали берите свои, а не из статьи.
Где спотыкаются
Доверяют userId из параметра запроса вместо принципала из контекста. Любой пользователь подставит чужой id, это классический IDOR.
Не знают про ThreadLocal в SecurityContextHolder и удивляются, что в асинхронном методе getAuthentication() возвращает null.
Кладут в JWT лишнее, вплоть до персональных данных, и выдают его на сутки. Payload читает любой, кто перехватил токен, а отозвать его до истечения срока без списка отозванных нельзя.