OAuth и федеративная аутентификация
Потоки OAuth2/OIDC/SAML и безопасность токенов — authorization-code flow, PKCE, state, проверка redirect_uri, id_token, валидация JWT, algorithm confusion и SAML signature wrapping.
12 вопросов
JuniorТеорияОчень частоЧто такое authorization-code flow в OAuth2 и почему по редиректу едет код?
Что такое authorization-code flow в OAuth2 и почему по редиректу едет код?
Пользователь аутентифицируется на authorization server, который редиректит обратно к клиенту с короткоживущим кодом. Клиент меняет код на токены прямым серверным вызовом. По редиректу едет только код, ведь URL попадают в логи.
Типичные ошибки
- ✗Думать, что в редиректе возвращается сам access token
- ✗Считать authorization code долговечным секретом, который стоит хранить
- ✗Полагать, что клиент отправляет пароль пользователя на authorization server
Уточняющие вопросы
- →Почему authorization code должен быть одноразовым и короткоживущим?
- →Чем клиент аутентифицирует сам себя на token endpoint?
JuniorТеорияОчень частоОт чего параметр state защищает редирект OAuth2 и каким образом?
От чего параметр state защищает редирект OAuth2 и каким образом?
state — неугадываемое значение, которое клиент генерирует, привязывает к сессии пользователя и шлёт в запросе авторизации. Сервер возвращает его в редиректе, а callback с несовпавшим state отвергается как подделанный.
Типичные ошибки
- ✗Генерировать
state, но не сверять его при приходе callback - ✗Хранить
stateбез привязки к сессии, из-за чего проходит любой callback - ✗Путать
stateсnonceв OIDC, который привязываетid_token
Уточняющие вопросы
- →Чем
stateотличается отnonceв слое идентификацииOpenID Connect? - →Где хранить
state, чтобы вторая вкладка браузера не ломала сверку?
MiddleТеорияОчень частоПочему redirect_uri сверяют точным совпадением и что позволяет нестрогая сверка?
Почему redirect_uri сверяют точным совпадением и что позволяет нестрогая сверка?
Authorization server сверяет запрошенный redirect_uri с зарегистрированным значением посимвольно — схема, хост, порт и путь. Префиксная сверка или wildcard уводят похожий URL на чужой путь, куда и уедет authorization code.
Типичные ошибки
- ✗Разрешать wildcard или префиксную сверку зарегистрированного URI
- ✗Оставлять open redirect на разрешённом хосте, который перебрасывает код дальше
- ✗Считать одноразовый код безобидным, куда бы он ни был доставлен
Уточняющие вопросы
- →Почему open redirect на разрешённом хосте обесценивает allowlist?
- →Как PKCE ограничивает ущерб, если код всё же попал не туда?
JuniorТеорияЧастоИз каких трёх частей состоит JWT и что сервер обязан сделать до доверия claims?
Из каких трёх частей состоит JWT и что сервер обязан сделать до доверия claims?
JWT состоит из header, payload и подписи в base64url, соединённых точками. Header и payload закодированы, но не зашифрованы, их читает любой держатель. До доверия claims сервер проверяет подпись, затем iss, aud и exp.
Типичные ошибки
- ✗Считать payload зашифрованным и класть секреты в claims
- ✗Раскодировать токен и доверять claims без проверки подписи
- ✗Проверить подпись, но не проверить
iss,audиexp
Уточняющие вопросы
- →Почему отзыв JWT требует коротких сроков жизни или denylist?
- →Какой ключ проверяет асимметрично подписанный токен и откуда он берётся?
MiddleТеорияЧастоЧто добавляет Proof Key for Code Exchange (PKCE) и зачем он публичным клиентам?
Что добавляет Proof Key for Code Exchange (PKCE) и зачем он публичным клиентам?
Клиент создаёт случайный code_verifier, отправляет его хеш как code_challenge в запросе авторизации, затем предъявляет verifier на token endpoint. Код обменивается только при совпадении, что привязывает его к начавшему поток.
Типичные ошибки
- ✗Считать, что PKCE заменяет
state, хотя они решают разные задачи - ✗Выбирать метод
plainвместоS256 - ✗Переиспользовать один
code_verifierмежду запросами авторизации
Уточняющие вопросы
- →Почему
S256предпочтительнее методаplain? - →Отменяет ли PKCE необходимость точной сверки
redirect_uri?
MiddleТеорияЧастоЧем в OpenID Connect различаются id_token и access_token по аудитории?
Чем в OpenID Connect различаются id_token и access_token по аудитории?
id_token — результат аутентификации для клиента: его aud равен client id, и он сообщает, кто вошёл. access_token — результат авторизации для API, непрозрачный клиенту. OAuth2 даёт доступ; OIDC говорит, кто пользователь.
Типичные ошибки
- ✗Отправлять
id_tokenв API как bearer-учётные данные - ✗Принимать валидный
access_tokenза доказательство личности пользователя - ✗Доверять непроверенному claim
emailпри поиске существующего аккаунта
Уточняющие вопросы
- →Почему непроверенный claim
emailнебезопасен как ключ аккаунта? - →Что ломается, если API начнёт принимать
id_tokenкак bearer-токен?
SeniorТеорияЧастоЧто такое algorithm confusion в JWT и как фиксация алгоритма это предотвращает?
Что такое algorithm confusion в JWT и как фиксация алгоритма это предотвращает?
Проверяющий, берущий алгоритм из header alg самого токена, может быть переведён с асимметричной схемы на симметричную, где публичный ключ — а он не секретен — становится ключом HMAC. Фиксируйте ожидаемый алгоритм и ключ издателя.
Типичные ошибки
- ✗Позволять библиотеке выбирать алгоритм по header токена
- ✗Считать публичный ключ секретом на том основании, что им проверяют подпись
- ✗Загружать ключ по значению
kidилиjku, пришедшему внутри токена
Уточняющие вопросы
- →Почему значение
kidилиjkuиз токена — недоверенный ввод? - →Как короткие сроки жизни и denylist вместе ограничивают задержку отзыва?
MiddleДебаггингИногдаВ логе шлюза принят токен с alg равным none — найдите и исправьте дефект
В логе шлюза принят токен с alg равным none — найдите и исправьте дефект
Шлюз раскодирует токен вместо проверки, поэтому токен без алгоритма не несёт подписи и всё равно принимается. Проверяйте фиксированным алгоритмом и ключом издателя, отвергайте любое иное значение alg, а claims читайте только после этого.
Типичные ошибки
- ✗Читать header
alg, чтобы решить, как проверять токен - ✗Вызывать помощник раскодирования, полагая, что он проверяет и подпись
- ✗Доверять claim
roleиз токена, который вообще не проверялся
Уточняющие вопросы
- →Почему принимаемый алгоритм должен фиксировать сервер, а не токен?
- →Что добавить, чтобы находить в этих логах другие случаи приёма непроверенных токенов?
MiddleТеорияИногдаКогда сервису нужен client credentials, а не поток от имени пользователя?
Когда сервису нужен client credentials, а не поток от имени пользователя?
Client credentials подходит фоновому сервису, действующему от себя — без пользователя, редиректа и согласия. Клиент аутентифицируется и получает токен со своей идентичностью. Scopes задают допустимое, поэтому выдавайте минимум прав.
Типичные ошибки
- ✗Использовать client credentials, чтобы действовать от лица конкретного пользователя
- ✗Выдавать один широкий набор scopes всем сервисам ради удобства
- ✗Путать scopes, ограничивающие действия, с claims, описывающими идентичность
Уточняющие вопросы
- →Почему машинному токену всё равно нужен короткий срок жизни?
- →Как ротировать client secret без простоя?
MiddleТеорияИногдаКакой grant в OAuth2 кому подходит и почему отказались от implicit и password?
Какой grant в OAuth2 кому подходит и почему отказались от implicit и password?
Браузерные, мобильные и серверные приложения от лица пользователя используют authorization code с PKCE; вызывающие без пользователя — client credentials. Implicit возвращал токены в URL, а password брал учётные данные, поэтому оба сняты.
Типичные ошибки
- ✗По-прежнему выбирать implicit для одностраничных приложений
- ✗Брать password grant, чтобы избежать редиректа в нативном приложении
- ✗Держать refresh-токены бессрочно без ротации и обнаружения повторного использования
Уточняющие вопросы
- →Чего достигает ротация refresh-токенов с обнаружением повторного использования?
- →Почему токен во фрагменте URL трудно удержать вне логов?
MiddleТеорияИногдаЧто связывает nonce в OIDC и какие claims id_token обязан проверить клиент?
Что связывает nonce в OIDC и какие claims id_token обязан проверить клиент?
Клиент кладёт случайный nonce в запрос авторизации и требует то же значение внутри id_token, привязывая токен к этому входу и блокируя повтор. Он также проверяет подпись издателя и сверяет iss, exp и aud.
Типичные ошибки
- ✗Проверить подпись, но пропустить сверку
aud - ✗Принимать
id_token, чейnonceне сверялся с сохранённым - ✗Доверять значению
issиз токена вместо фиксации ожидаемого издателя
Уточняющие вопросы
- →Почему
nonceзащищаетid_token, аstate— callback? - →Как клиент узнаёт, каким опубликованным ключом проверять данный
id_token?
SeniorТеорияИногдаКак токены утекают через referrer и логи и что чинит ограничение аудитории?
Как токены утекают через referrer и логи и что чинит ограничение аудитории?
Всё, что попало в URL — токен во фрагменте или query — оказывается в истории браузера, логах прокси и заголовках Referer, поэтому токенам место в заголовках. Ограничение аудитории отдельно: токен называет своё API.
Типичные ошибки
- ✗Логировать полные URL запросов, в которых остались токены или коды авторизации
- ✗Считать, что валидная подпись означает и предназначенность токена этому API
- ✗Принимать вход, инициированный провайдером, без начатого клиентом потока
Уточняющие вопросы
- →Почему вход по инициативе провайдера слабее входа, начатого клиентом?
- →Как клиенту не перепутать ответы, пришедшие от двух настроенных издателей?