Получить доступ

Аутентификация: JWT, OAuth2/OIDC и method security

Структура и валидация JWT, проблема отзыва, роли OAuth2 и authorization code flow, OIDC, и авторизация на уровне методов.

JWT: структура и валидация

JWT — самодостаточный токен из трёх частей через точку: header.payload.signature (каждая — base64url). В payload лежат claims (sub, iss, aud, exp, роли), а signature — подпись (HMAC на секрете или RSA/EC на паре ключей).

Resource server (ваше API) проверяет подпись, issuer (iss), audience (aud) и срок (exp), а затем маппит claims в authorities. Важно: payload ПОДПИСАН, но НЕ зашифрован — его может прочитать любой. Поэтому секреты в JWT не кладут.

Классическая атака — подмена алгоритма в header. alg:none: злоумышленник ставит заголовок "alg":"none" и шлёт токен без подписи; наивная библиотека «проверяет» подпись none и принимает токен. Algorithm confusion: токен, который сервер ждёт подписанным RSA (RS256, проверка публичным ключом), злоумышленник переподписывает HMAC (HS256), используя публичный RSA-ключ как HMAC-секрет. Защита одна: сервер должен жёстко фиксировать ожидаемый алгоритм и не доверять полю alg из токена. В Spring Security это закрыто из коробки (NimbusJwtDecoder с заданным алгоритмом) — главное не отключать и не «чинить» проверку вручную.

Отзыв и refresh

Цена stateless-самодостаточности: выданный JWT нельзя «отозвать» до истечения — сервер его не хранит и не отслеживает. Если токен украли, он валиден до exp.

Поэтому на практике используют короткоживущий access-токен (минуты) плюс долгоживущий refresh-токен, который хранится и может быть отозван на сервере; access обновляют по refresh. Для немедленного отзыва ведут blacklist/версионирование — это уже добавляет состояние, размывая «чистый stateless».

OAuth2: роли и flow

OAuth2 — протокол делегированного доступа с тремя ролями: authorization server выдаёт токены, resource server защищает API и проверяет токены (это типичная роль Spring-приложения, oauth2ResourceServer), client получает токен от имени пользователя.

Базовый сценарий — authorization code flow: пользователь логинится у authorization server, приложение получает короткоживущий code, меняет его на токены на бэкенде. Так пароль пользователя не проходит через ваше приложение.

Поток OAuth2 между клиентом, сервером авторизации и ресурс-сервером: запрос авторизации, согласие пользователя, код авторизации, обмен кода на токен, доступ к ресурсу по access-токену.
OAuth2 authorization code flow: код авторизации обменивается на access-токен, с которым клиент идёт к ресурс-серверу.

OIDC

OpenID Connect (OIDC) — слой identity поверх OAuth2. Если чистый OAuth2 — про ДОСТУП (authorization), то OIDC добавляет id_token (тоже JWT) с информацией о пользователе и нужен для ЛОГИНА (authentication) через внешнего провайдера (Google, Keycloak, Okta).

Различайте: access_token — для вызова API, id_token — чтобы узнать, кто вошёл. Spring поддерживает обе роли (oauth2Login для клиента, oauth2ResourceServer для API).

Method security

Кроме авторизации по URL, права проверяют на уровне методов: @EnableMethodSecurity включает @PreAuthorize/@PostAuthorize (с выражениями SpEL) и @Secured. Это полезно, когда один сервисный метод вызывается из разных точек входа (REST, очередь, шедулер) — защита в одном месте.

Method security работает через AOP-прокси, поэтому наследует ту же ловушку self-invocation (вызов через this мимо прокси не проверяется). И не ограничивайтесь ролями — часто нужна проверка владения объектом (ownership).

@PreAuthorize("hasAuthority('ORDER_READ') and @acl.canReadOrder(#id)") // роль + ownership
OrderDto getOrder(long id) { /* ... */ }

Как отвечать на собеседовании

Опишите JWT (header.payload.signature, подписан но не зашифрован → без секретов; сервер проверяет подпись/iss/aud/exp) и главную проблему — отзыв (короткий access + refresh). Различите роли OAuth2 (resource server/client/authorization server) и authorization code flow, и OIDC как identity-слой (id_token, логин) против OAuth2 (доступ). Завершите method security через AOP (@PreAuthorize, self-invocation, ownership, а не только роли).

Вопросы по теме

Читайте также

Закрытая бета

Знать тему — половина дела

На живом собеседовании sotto слышит вопрос интервьюера и показывает короткий ответ и план. Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем