OIDC часто описывают как «получить JWT после логина». Это слишком краткая модель. Настоящая ценность протокола — строгие правила, по которым участники доверяют друг другу.
Приложение инициирует вход
Приложение создаёт случайный state для привязки ответа к инициированному запросу. Для OIDC используется также nonce, который затем должен согласоваться с ID token. Для публичного клиента PKCE особенно важен: он связывает запрос авторизации и обмен кода на токены.
Браузер перемещается между сторонами
После проверки параметров авторизации IdP проводит аутентификацию. Затем пользовательский агент возвращается на заранее разрешённый redirect URI с authorization code. Код сам по себе не должен быть достаточным, чтобы постороннее приложение получило токены.
Обмен кода — отдельная проверка
При обмене кода клиент отправляет code_verifier, который должен соответствовать ранее переданному code_challenge. Сервер проверяет условия использования кода, клиента и перенаправление.
ID token и access token — не одно и то же
ID token описывает событие аутентификации для клиента OIDC. Access token предназначен ресурсному серверу. API должен проверять, что токен выдан доверенным issuer, не истёк, имеет нужную аудиторию и соответствует ожидаемому назначению. Наличие корректной подписи не означает автоматического права на все операции.
Что проверять в тестах
- Неверный redirect URI.
- Повторное использование authorization code.
- Несовпадение code_verifier.
- Ошибочный issuer, audience или nonce.
- Истёкший токен, несоответствующий алгоритм подписи.
Хорошая реализация отличается от демонстрации не успешным login flow, а тем, как она отвергает некорректные запросы.
Для интеграции с RustCloak необходимо опираться на discovery-документ и тесты конкретной версии, а не на предположение, что пути endpoints совпадают с другим IdP.
Почему redirect URI сравнивают строго
Если сервер допускает произвольные адреса перенаправления, authorization code может попасть не тому приложению. Поэтому URL ответа должен сверяться с зарегистрированной конфигурацией клиента. Подстановки wildcard, случайные альтернативные домены и неочевидные изменения схемы HTTP/HTTPS — типичные причины рисков.
PKCE не заменяет остальные проверки
PKCE защищает связь между началом потока и использованием кода. Он не отменяет проверку state, согласованный issuer и правила CORS/cookies. Для каждой защиты есть собственная задача. Важнее не количество параметров, а то, что сервер их проверяет в правильный момент.
Токены нужно адресовать конкретному получателю
Допустим, сервису A предъявили access token, предназначенный сервису B. Даже при корректной подписи и действующем сроке этот токен не должен автоматически приниматься сервисом A. Аналогично ID token не следует использовать как замену access token для произвольного API.
В реальной реализации поведение зависит от формата токена, audience, scopes и контракта resource server. Важно документировать этот контракт до написания middleware, а затем подтверждать его интеграционными тестами.
Сессия и токен живут по разным правилам
Завершение браузерной сессии не означает, что все выпущенные ранее токены мгновенно становятся недействительными. При проектировании logout, revoke и rotation заранее определяют допустимый срок жизни, механизм обновления и поведение сервисов при смене ключей.
Пример тестовой матрицы
Для каждого клиента повторите набор сценариев: корректный вход, неправильный redirect URI, отсутствие PKCE, истёкший код, повторный code exchange, несоответствие nonce, недоступный JWKS endpoint и смена подписывающего ключа. Так можно обнаружить не только ошибки happy path, но и несогласованность участников потока.
Вывод для RustCloak
Публикация OIDC API должна сопровождаться совместимостными тестами и документацией issuer/discovery. Кнопка «Войти» — только верхний слой: надёжность протокола определяется предсказуемостью в самых неприятных сценариях.