Публикация в блоге duendesoftware 20.05.2025, перевод 12.12.2025
Ключевые повороты в истории OAuth и OpenID Connect
Перевод Дмитрия Грудинина
статьи авторов Joe DeCock, Khalid Abuhakmeh, Brett Hazen
в блоге duendesoftware.com
Как и любое технологическое достижение, современные решения в области безопасности — это результат кумулятивных усилий и вклада множества людей, чья преданность делу привела к созданию по-настоящему выдающегося инструмента. Нынешний уровень защищённости приложений — заслуга талантливых экспертов, серьёзно относящихся к безопасности и объединившихся ради создания технологий, от которых выигрываем мы все. Без них каждая компания до сих пор изобретала бы велосипед — собственные, уникальные, но зачастую уязвимые и несовместимые решения. Слава стандартам — они спасли нас от хаоса!
Хронология OAuth 2.0 и OpenID Connect
Исходная иллюстрация хронологии развития OpenID Connect
Хотя рабочие группы IETF (Internet Engineering Task Force) и OpenID Foundation создали множество стандартов, мы отобрали лишь те, что оказали наибольшее влияние на реализацию безопасности в современной разработке приложений — особенно в контексте OAuth и OpenID Connect.
OAuth 2.0
Апрель 2010 — октябрь 2012・RFC 6749
В начале 2010 года участники из Microsoft, Yahoo! и Google предложили спецификацию под названием OAuth Web Resource Authorization Profiles (OAuth WRAP) для замены OAuth 1.0, который разработчики считали слишком сложным в использовании из-за необходимости канонизировать HTTP-сообщения. В OAuth WRAP использовались токены-носители (bearer tokens), а не токены с подтверждением владения (proof-of-possession tokens), — ещё одно упрощение по сравнению с OAuth 1.0. Эта спецификация была передана в рабочую группу OAuth в IETF и в октябре 2012 года оформилась как OAuth 2.0. Фреймворк авторизации OAuth 2.0 позволяет сторонним приложениям получать ограниченный доступ к ресурсам через HTTP-эндпоинт. Спецификация даёт владельцам ресурсов возможность одобрять взаимодействие между ними, сторонним приложением и защищаемым ресурсом.

Вы, вероятно, видели экран согласия при входе в сервисы с использованием социальной аутентификации (например, через аккаунт Google или Facebook). Для разработчиков инструменты таких сервисов, как GitHub или GitLab, используют OAuth для доступа к защищённым компонентам — таким как репозитории, системы отслеживания задач и другие ресурсы.
OpenID Connect
Март 2010 — февраль 2014・OpenID Connect
Стандарт OpenID Connect на сегодняшний день является наиболее широко используемым протоколом аутентификации. Он охватывает сценарии использования от мобильных и веб-приложений до корпоративных и облачных решений и может применяться на высоких уровнях безопасности. Это протокол, которым все пользуются ежедневно, даже не осознавая этого, поскольку он работает «под капотом» — как инфраструктурная технология, а не как потребительский бренд.

Как видно из хронологии, он разрабатывался параллельно с OAuth 2.0, JWT, JWS, JWE, JWK, JWA и другими протоколами и форматами данных, при этом все эти спецификации взаимно влияли друг на друга в процессе стандартизации. Трудно представить современную онлайн-безопасность без OpenID Connect.
JSON Web Token (JWT)
Октябрь 2010 — май 2015・RFC 7519
Трудно представить эпоху веб-безопасности, когда JSON Web Tokens (JWT) ещё не существовали, но такая эпоха действительно была. Сегодня JWT практически синонимичен современным практикам обеспечения безопасности — и, кстати, в мае 2025 года ему исполняется 10 лет. Разработка спецификаций JWT, JWS, JWE, JWK и JWA началась в октябре 2010 года. Формат позволяет сторонам передавать защищённые JSON-полезные нагрузки, которые кодируются и подписываются с помощью JSON Web Signature (JWS) и/или шифруются с применением JSON Web Encryption (JWE). Он обеспечивает простое, но чёткое представление защищённых утверждений (claims), что сыграло ключевую роль в достижении реальной совместимости в области безопасности.
«Мы разрабатывали JWT как простой и универсальный формат токенов на основе JSON. Конечно, у нас на уме были сценарии использования в области идентификации — в первую очередь ID-токены. Однако в то время мы и не подозревали, что JWT в итоге начнут применяться для самых разных других целей. Например, в 2020 году я узнал, что JWT помогают бороться с мошенническими и нежелательными телефонными звонками, обеспечивая подлинность информации в Caller ID. Один из признаков успешного стандарта — его применение в задачах, о которых авторы изначально даже не задумывались!»

Майк Джонс
Майк Джонс, автор ряда широко применяемых спецификаций OpenID, OAuth, JOSE, COSE, ACE и SecEvent.
Автор блога
self-issued.info
Proof Key for Code Exchange или PKCE
Июль 2013 — сентябрь 2015・RFC 7636
По мере роста популярности OAuth он, к сожалению, привлёк внимание злоумышленников. В июле 2013 года Нат Сакимура и несколько других авторов предложили механизм Proof Key for Code Exchange (PKCE) для защиты от атак, основанных на перехвате кода авторизации. Суть в том, что если злоумышленник получает код авторизации, он может использовать его для получения токена доступа.

PKCE решает эту проблему путём введения криптографически сгенерированного случайного ключа. Предоставим слово авторам спецификации:
«Для смягчения данной атаки в этом расширении используется динамически создаваемый криптографически случайный ключ, называемый „code verifier“ (верификатор кода). Для каждого запроса авторизации формируется уникальный верификатор кода, а его преобразованное значение — „code challenge“ (вызов кода) — отправляется на сервер авторизации вместе с запросом кода авторизации. Полученный код авторизации затем передаётся на эндпоинт токена вместе с исходным „code verifier“, и сервер сравнивает его со значением, полученным ранее в запросе, чтобы убедиться, что клиент действительно владеет этим „code verifier“. Поскольку верификатор передаётся по защищённому TLS-соединению и не может быть перехвачен, данная схема эффективно предотвращает атаку: злоумышленник не сможет подобрать этот одноразовый ключ.»

Стандарт Proof Key for Code Exchange (PKCE)
Коротко говоря, даже если злоумышленник перехватит код авторизации, он не сможет обменять его на токен доступа — поскольку у него не будет оригинального секретного верификатора.
OAuth 2.0 Authorization Server Metadata
Ноябрь 2015 — июнь 2018 ・ RFC 8414
Возможность публикации метаданных сервера авторизации значительно упростила взаимодействие компонентов OAuth, разрабатываемых различными сторонами. Вместо того чтобы получать информацию о конфигурации сервера авторизации (например, URL эндпоинтов) из документации для разработчиков, её теперь можно получать программно непосредственно из опубликованных метаданных. Это снижает вероятность ошибок и делает процесс более удобным.
Mutual-TLS Client Authentication
и Certificate-Bound Access Tokens
Октяюрь 2016 — февраль 2020 ・ RFC 8705
Некоторые организации высоко ценят уровень безопасности и уверенность, которые обеспечивают цифровые сертификаты. Хотя сертификаты управлять сложнее, чем строковые секреты, инфраструктура, построенная вокруг них (в частности, PKI), делает крайне затруднительным создание поддельной копии.

В октябре 2016 года группа авторов предложила концепцию привязки токенов доступа и обновления к сертификатам посредством взаимной аутентификации на уровне транспортного слоя (mTLS) с использованием сертификатов X.509. Применение сертификатов обеспечивает доверительные отношения между клиентом и сервером: сервер авторизации выдаёт токены только тому клиенту, которому принадлежит подтверждающий сертификат.
Resource Indicators for OAuth 2.0
Март 2016 — февраль 2020 ・ RFC 8707
По мере развития потребностей разработчиков OAuth эволюционируют и соответствующие спецификации. В марте 2016 года было предложено расширение OAuth 2.0, позволяющее клиентам явно указывать, на каком сервере ресурсов будет использоваться выдаваемый токен доступа. Эта дополнительная информация даёт серверу авторизации возможность принимать более обоснованные решения о том, какие политики безопасности следует применить, что, в свою очередь, может повлиять на формат и содержимое самого токена.

Хотя данное изменение может показаться незначительным, оно существенно расширяет возможности разработчиков серверов авторизации по созданию безопасных решений для всё возрастающего числа потребителей.
JWT-Secured Authorization Request (JAR)
Февраль 2014 — август 2021 ・ RFC 9101
Окончательная спецификация OpenID Connect Core, утверждённая в феврале 2014 года, стандартизировала использование подписанных Request Objects (объектов запроса). До этого параметры авторизационного запроса передавались в виде URI-параметров. Как можно предположить, такой подход имел ограничения и потенциальные риски с точки зрения безопасности: во-первых, URI имеют ограничения по длине, а во-вторых, системы аудита могут случайно записывать в логи чувствительные данные, которые затем могут быть извлечены злоумышленниками.

RFC 9101 перенесла определение подписанных Request Objects из OpenID Connect Core в отдельную OAuth-спецификацию, сделав тем самым поддержку подписанных запросов доступной и вне контекста OpenID Connect.

Согласно этой спецификации, параметры запроса могут передаваться:
  • по значению — в виде JWT, включённого непосредственно в тело HTTP-запроса,
  • или по ссылке — с помощью URL, указывающего на JWT, содержащий параметры запроса.

Такие JWT могут быть подписаны и, при необходимости, зашифрованы. При передаче по ссылке они не подвержены ограничениям на размер.

Хотя некоторые устаревшие реализации всё ещё встречаются, многие серверы авторизации уже перешли на JWT-защищённые авторизационные запросы благодаря их очевидным преимуществам.
Pushed Authorization Requests или PAR
Сентябрь 2019 — сентябрь 2021 ・ RFC 9126
До появления данной RFC взаимодействие между сервером авторизации и клиентом всегда происходило по stateless-схеме через агент пользователя, например, веб-браузер. Хотя такой подход остаётся безопасным, он имеет определённые ограничения.
RFC, вводящая Pushed Authorization Requests (PAR), предложила механизм, при котором клиент может передавать параметры запроса авторизации серверу авторизации через backchannel («фоновый канал», т. е. напрямую, без участия браузера). Это требует, чтобы сервер сохранял состояние ожидающих обработки запросов.

PAR позволяет серверу авторизации аутентифицировать клиента до начала какого-либо взаимодействия с пользователем. Более высокая степень уверенности в подлинности клиента на раннем этапе процесса авторизации даёт серверу возможность отклонять недобросовестные запросы ещё до их дальнейшей обработки — что помогает предотвращать подмену клиентов, а также иные формы подделки, вмешательства или несанкционированного использования запросов авторизации.

Для разработчиков на ASP.NET Core наш коллега Джо ДеКок (Joe DeCock) реализовал поддержку PAR в .NET.
Demonstrating Proof of Possession (DPoP)
Март 2019 — сентябрь 2023 ・ RFC 9449
Атаки повторного использования (replay-атаки) — распространённый вектор для злоумышленников. Если атакующий получает доступ к валидному токену, он может выступать от имени первоначального владельца. Механизм Demonstrating Proof of Possession (DPoP) определяет способ подтверждения владения токеном, защищающий все стороны от атак повторного использования, направленных на токены доступа, а в некоторых случаях — и на токены обновления.

DPoP представляет собой механизм подтверждения владения токеном на уровне приложения, ограничивающий использование токенов доступа и обновления OAuth [RFC6749] конкретным отправителем. Он позволяет клиенту подтвердить владение парой ключей (публичным и приватным), включая заголовок DPoP в HTTP-запрос. Значением этого заголовка является JSON Web Token (JWT) [RFC 7519], на основе которого сервер авторизации может привязать выданные токены к публичному ключу из клиентской пары. Получатели таких токенов затем могут проверить эту привязку, убедившись, что клиент, предъявляющий токен, действительно владеет соответствующим приватным ключом (что подтверждается подписью в заголовке DPoP). Иными словами, легитимным владельцем токена может быть только тот отправитель, который доказал владение приватной частью ключевой пары.

Привязка токенов к криптографическим ключам, чьи приватные ключи никогда не раскрываются в рамках протокола, делает невозможным использование перехваченных токенов: у злоумышленника нет приватного ключа, защищающего эти токены. Клиент всегда сохраняет приватный ключ у себя и никогда не передаёт его серверу — хотя доказательство владения им (в виде цифровой подписи) отправляется в составе заголовка DPoP. Это обеспечивает более высокий уровень защиты по сравнению с «токенами-носителями» (bearer tokens), ранее являвшимися стандартом для OAuth 2.0. Пары приватных и публичных ключей — отличное решение [RFC 6750].
FAPI 2.0
Март 2021 — февраль 2025 ・ FAPI 2.0 Security Profile
FAPI 2.0 — это профиль безопасности, объединяющий несколько стандартов, которые организации рекомендуется внедрять для формирования уровня защиты, соответствующего ценности защищаемых ресурсов. Такие ресурсы, как правило, встречаются в сфере финансовых услуг, электронного здравоохранения и электронного правительства, но не ограничиваются ими. Если вы работаете с чувствительными данными или стремитесь к повышенному уровню безопасности, FAPI 2.0 — это то, с чем стоит ознакомиться.

Реализация подхода FAPI 2.0 сопряжена с дополнительными накладными расходами и затратами на сопровождение, что может быть избыточным для некоторых сценариев обеспечения безопасности. Окончательная версия FAPI 2.0 была утверждена в феврале 2025 года. Она основана на опыте разработки и внедрения FAPI 1.0, завершённого в марте 2021 года.
Заключение
Упорный труд IETF и OIDF значительно укрепил информационную безопасность: OAuth и OpenID Connect сегодня лежат в основе большей части механизмов безопасности в современной разработке. Поскольку сотрудники Duende регулярно участвуют в этих совещаниях, мы вспомнили множество содержательных дискуссий, в которых принимали участие, и решили выделить несколько наших любимых и наиболее значимых спецификаций за последние 15 лет. Но нам было бы очень интересно узнать и о ваших предпочтениях.

Если у вас есть любимый стандарт OpenID или RFC (давайте будем честны — они есть у каждого!), пожалуйста, поделитесь им в комментариях. Как всегда, мы внимательно следим за новейшими разработками OIDF и IETF и активно участвуем в рабочих группах, чтобы внедрять передовые практики безопасности в экосистему .NET.