«Без понимания различий между авторизацией и аутентификацией легко построить уязвимую систему. OAuth и OIDC — это не два варианта одного, а два уровня решения разных задач, где один строится поверх другого. Их совместное использование создаёт современный и, что важнее, безопасный доступ к данным.»
Основы: зачем нужны два протокола
Делегированный доступ и подтверждение личности — это фундаментально разные процессы, требующие разных механизмов безопасности. OAuth 2.0 был создан для безопасной авторизации. Он решает задачу: как дать стороннему приложению доступ к вашим данным в другом сервисе (например, к фото в облачном хранилище), не передавая ему ваш пароль.
OpenID Connect (OIDC) появился позже для решения задачи аутентификации. В его основе лежит вопрос: как доказать, что пользователь, который дал доступ к своим данным, — это именно он? OIDC использует инфраструктуру OAuth 2.0, но добавляет к ней обязательные гарантии и данные о личности.
Ключевое различие в двух предложениях
- OAuth 2.0 выдаёт access_token — ключ к определённым действиям (прочитать почту, изменить профиль). Это фреймворк делегирования полномочий.
- OpenID Connect добавляет к нему id_token — криптографически подписанное удостоверение личности пользователя (стандарт JWT). Это протокол аутентификации.
Архитектура OAuth 2.0: кто участвует и как
Работу OAuth обеспечивают четыре ключевых участника.
| Роль | Описание и пример |
|---|---|
| Владелец ресурса | Конечный пользователь, который владеет данными или доступом. Например, вы, как пользователь соцсети. |
| Клиент | Приложение, запрашивающее доступ от вашего имени. Это может быть веб-сайт, мобильное или десктопное приложение. |
| Сервер авторизации | Сервис, который аутентифицирует владельца ресурса и выдаёт токены клиенту. Это, например, сервис Яндекса, ВКонтакте или внутренний корпоративный Identity Provider. |
| Ресурсный сервер | API или служба, которая хранит защищённые данные и принимает для доступа токены. Например, API для доступа к вашему диску или календарю. |
Маршруты получения токенов: типы грантов
Тип гранта (grant type) определяет, каким способом клиент получит токен доступа. Выбор зависит от того, где выполняется код клиента и насколько ему можно доверять хранение секретов.
| Тип гранта | Для каких клиентов | Безопасность и статус |
|---|---|---|
| Authorization Code (с PKCE) | Веб-приложения (серверные и SPA), нативные приложения | Рекомендуемый, наиболее безопасный. Использует двухэтапный обмен: код авторизации -> токен. PKCE защищает от атак с подменой кода. |
| Implicit | Исторически для SPA в браузере | Устарел и не рекомендуется. Токен передавался напрямую в URL браузера, что создавало риски утечки. |
| Resource Owner Password Credentials | Только высоко доверенные first-party приложения (официальные клиенты) | Применяется в особых случаях. Пользователь напрямую передаёт логин и пароль клиенту, что противоречит основной идее OAuth. |
| Client Credentials | Сервис-сервисная коммуникация (machine-to-machine) | Для авторизации без участия пользователя. Клиент использует свои учётные данные (client_id/secret). |
Токены: что они делают и где живут
- Access Token: Короткоживущий ключ для доступа к API. Передаётся в заголовке
Authorization: Bearer <token>к ресурсному серверу. Может быть в формате JWT (подписанная структура) или opaque (случайная строка, которую нужно проверять на сервере авторизации). - Refresh Token: Долгоживущий токен для обновления access token. Используется только между доверенным клиентом и сервером авторизации. Никогда не отправляется к ресурсному серверу и должен храниться максимально безопасно (HttpOnly куки, secure storage).
Как OIDC добавляет аутентификацию к OAuth
OpenID Connect — это надстройка, которая стандартизирует три критически важных компонента.
- ID Token (JWT): Основной элемент. Это подписанный токен, который содержит утверждения (claims) о пользователе: уникальный идентификатор (
sub), издателя (iss), время выдачи и истечения. Клиент обязан криптографически проверить его подпись и все обязательные поля. - UserInfo Endpoint: Защищённый API-эндпоинт. Клиент, имея валидный access token, может запросить по нему дополнительные данные профиля (имя, аватар, телефон), которые могли не поместиться в ID Token.
- Discovery & Dynamic Registration: Механизмы для упрощения интеграции. Сервер авторизации предоставляет по фиксированному адресу (например,
/.well-known/openid-configuration) JSON-документ со всеми необходимыми для работы endpoints, типами подписей и другими параметрами.
Поток аутентификации OIDC (Authorization Code Flow)
- Инициация: Пользователь на клиенте нажимает «Войти через…». Клиент перенаправляет браузер на сервер авторизации со scope=
openidи другими запрошенными scope (например,profile email). - Аутентификация и согласие: Пользователь вводит свои учётные данные на стороне провайдера (OIDC) и видит запрос на предоставление прав клиенту.
- Получение кода: После успеха сервер авторизации возвращает браузер на указанный
redirect_uriклиента с одноразовым кодом авторизации. - Обмен кода на токены: Клиент (его backend) отправляет этот код вместе со своим секретом (если он конфиденциальный) на
token endpointсервера авторизации. В ответ получает набор токенов:id_token,access_token, часто такжеrefresh_token. - Валидация id_token: Клиент проверяет подпись JWT, соответствие издателя (
iss), аудитории (aud), временные метки и параметрnonceдля защиты от replay-атак. - Запрос дополнительных данных (опционально): При необходимости клиент вызывает
UserInfo endpoint, используя полученныйaccess_token.
Параметры безопасности, которые нельзя игнорировать
- state: Случайная строка, генерируемая клиентом перед началом потока и привязываемая к сессии пользователя. Сервер авторизации возвращает её обратно. Сравнение значений защищает от CSRF-атак, когда злоумышленник может подставить свой код авторизации.
- nonce: «Одноразовый номер», также генерируемый клиентом и передаваемый в начальном запросе. Он должен быть включён в полученный
id_token. Проверка гарантирует, что токен был выдан в ответ на ваш конкретный запрос, а не является результатом replay-атаки.
Применение в российской практике: что выбрать и как внедрить
Выбор протокола диктуется бизнес-задачей. Если приложению нужен только доступ к API другого сервиса (например, загрузить файл на корпоративный портал или отправить данные в CRM) — достаточно OAuth 2.0. Если требуется реализовать вход в систему, узнать, кто именно вошёл, и создать для него сессию — необходим OpenID Connect.
Многие популярные сервисы, включая отечественные, предоставляют поддержку обоих протоколов, что позволяет использовать их как для единого входа (SSO), так и для интеграций.
Критичные практики для безопасной реализации
- Всегда используйте Authorization Code Flow. Для публичных клиентов (SPA, мобильные приложения) обязательно применяйте расширение PKCE (Proof Key for Code Exchange). Оно защищает от перехвата кода авторизации.
- Откажитесь от Implicit Flow. Все современные спецификации и руководства по безопасности (включая рекомендации ФСТЭК в части построения SSO) считают этот поток устаревшим и небезопасным.
- Валидируйте все токены полностью. Для JWT проверяйте не только наличие, но и алгоритм подписи (отвергайте
none), издателя (iss), аудиторию (aud), срок действия. Используйте для проверки открытые ключи сервера авторизации (JWKS). - Управляйте временем жизни токенов: access token — минуты, refresh token — дни или недели. Краткая жизнь access token минимизирует риски при его компрометации.
- Безопасно храните refresh token: В веб-приложениях — в HttpOnly, Secure, SameSite куках. В мобильных — в защищённом хранилище ОС (Keystore/Keychain).
Внедрение OAuth 2.0 и OpenID Connect с соблюдением этих практик позволяет создать не просто удобную, но и соответствующую современным требованиям к защите информации систему управления доступом, что особенно актуально в контексте выполнения требований регуляторов.