- PVSM.RU - https://www.pvsm.ru -
Эта статья повествует о наиболее распространенном методе обмена токенами в потоке OpenID Сonnect: грантах [grants]. Обещаем – путешествие будет увлекательным, так что устраивайтесь поудобнее.

Периодически все мы сталкиваемся с ситуациями, когда приходится удостоверять свою личность, например, оплачивая счета, покупая билеты на самолет или даже посещая ночные клубы. Обычно это не проблема – паспорт есть у каждого. Получается, что власти страны, выдавшей паспорт, подтверждают личность получившего его гражданина.
Токен – это аналог паспорта в Интернете. Он содержит:
сведения о пользователе;
подпись эмитента;
срок действия.
Именно здесь в игру вступает OpenID Connect (OIDC). Этот протокол основан на спецификации OAuth2 [1] и выступает сетевым аналогом паспорта со всеми необходимыми подписями, которые запрашиваются соответствующими проверяющими сервисами (также известными как relying parties, RPs). Токены выпускаются и подписываются поставщиками удостоверений (identity providers, IdPs) – этаким цифровым аналогом паспортного стола.
В итоге у нас есть проверяющая сторона, которая запрашивает токен, и поставщик идентификационных данных, который эти токены выпускает. Так что же дальше? Как получить токен и куда обращаться за ним?
Существует множество грантов, т.е. способов взаимодействия с IdP с целью получения токена. Большинство из них типичны и широко распространены. Некоторые выделяются особенностями, связанными с IdP.
Информация о поддерживаемых грантах публична; получить ее можно, направив запрос на endpoint IdP:
curl 'https://your-idp.com/.well-known/openid-configuration'
| jq .grant_types_supported
["authorization_code","refresh_token","urn:ietf:params:oauth:grant-type:device_code"]
А теперь давайте рассмотрим особенности, плюсы и минусы самых популярных грантов OIDC.
Грант по коду авторизации [2] (Authorization Code) – это главная ценность протокола OIDC и основная причина, по которой он был вообще изобретен. В гранте участвуют все три стороны: пользователь, IdP и RP.
Пользователь инициирует процесс, обратившись к endpoint'у авторизации IdP и обменивает учетные данные на... образ токена (или, как мы его называем, код) вместо самого токена. Вооружившись кодом, пользователь идет к проверяющей стороне. Получив код, последняя запрашивает токен у IdP через соответствующий endpoint.

Плюсы:
Кроме IdP, никто не видит учетные данные пользователя;
RP получает токен непосредственно от доверенного IdP.
Минусы:
Процесс завязан на браузер пользователя, что невозможно при межмашинном взаимодействии;
Злоумышленники могут перехватить код;
Требуется трехсторонняя связь между всеми участниками процесса: пользователем, RP и IdP.
PKCE [3] – это дальнейшее развитие концепции предыдущего гранта, предотвращающее возможность кражи кода. В Authorization Code уязвимым звеном является пересылка кода пользователем проверяющей стороне. Откуда мы знаем, что это та самая RP? Злоумышленник может занять ее место, как это сделал волк, прикинувшись бабушкой в Красной шапочке. То есть принцип «Никому не верь» актуален всегда.
Впрочем, идея proof key не особенно сложна. Пользователь всего лишь должен сообщить RP, как расшифровать код, а IdP – как его зашифровать. И все!

Получить поддерживаемые методы проверки кода можно, запросив endpoint IdP:
curl 'https://your-idp.com/.well-known/openid-configuration'
| jq .code_challenge_methods_supported
["S256","plain"]
Этот грант [4] был разработан для аутентификации в одностраничных приложениях (SPA). Он похож на грант Authorization Code. Разница лишь в том, что при перенаправлении пользователь получает реальный токен в качестве GET-параметра, а не код (который образ токена, помните?).

Плюсы:
SPA не нужно делать POST-запрос к IdP (что может быть запрещено механизмом CORS).
Минусы:
Злоумышленники могут получить доступ к токенам в истории браузера;
Невозможно выпустить токен обновления (refresh token).
Удобство этого потока не столь существенно, поскольку он приводит к созданию огромной дыры в безопасности. Рекомендуем отказаться от неявного гранта в пользу гранта по коду авторизации.
Также пользователь может предоставить [5] свои учетные данные проверяющей стороне, чтобы та получила токен от его имени. Однако раскрывать свои пароли кому бы то ни было – не самая лучшая идея. Этот грант можно использовать только в случаях, когда вы абсолютно уверены в RP. Однако, как упоминалось ранее, верить нельзя никому.

Этот грант существует только потому, что иногда можно поступиться безопасностью ради удобства, но все же использовать его не рекомендуется [6]. Подумайте дважды, прежде чем им воспользоваться.
Плюсы:
Можно использовать для аутентификации CLI-приложений;
Можно использовать для межмашинной связи;
Хорошо подходит для автоматизации, так как со стороны пользователя требуется лишь один запрос.
Минусы:
Может произойти утечка данных;
Данный подход заставляет пользователей делиться своими учетными данными с кем-то кроме IdP.
Этот грант [7] позволяет получить токен проверяющей стороне. Нечто вроде паспорта для паспортного стола.
Пользователь в процессе не участвует. Такой токен наделяет полномочиями саму RP – например, на осуществление дополнительных обращений на API IdP.

Плюсы:
Интересная возможность.
Минусы:
Этот грант не касается пользователей, так что нам он не особо интересен.
Наши паспорта действительны на протяжении многих лет, но представьте себе паспорт, срок действия которого истекает через 5 или 10 минут. В реальной жизни это было бы похоже на ад и нам приходилось бы получать новый паспорт всякий раз, когда возникает необходимость удостоверить личность (например, при покупке авиабилетов).
Авиакомпании всегда хотят самые свежие фотографии и данные. Именно поэтому срок действия столь короткий. По той же причине процедура обновления должна быть максимально простой, чтобы пользователи не потеряли рассудок от бюрократии и проволочек. То есть она должна выглядеть примерно так: «Привет! Это снова я. Пришли мне, пожалуйста, новый паспорт».
К счастью, такая процедура существует и называется Refresh Token. Этот специальный токен можно поменять на новый идентификационный токен без участия пользователя.

Плюсы:
Удобство;
Refresh Token – это токен длительного действия, который отправляется исключительно в IdP, а это самый безопасный способ получения токена.
Минусы:
Его можно использовать только для продления срока действия токена;
Требуется доступ к IdP.
«Хорошо, – скажете вы, – но что, если мне нужен паспорт для холодильника, микроволновки или пылесоса?» Ура! Протокол OIDC широко применяется и в Интернете вещей. Единственная сложность – как получить токен, если у холодильника нет браузера или терминала?
Прежде всего устройство должно знать URL-адрес, чтобы инициировать аутентификацию. Для этого следует послать запрос на discovery endpoint поставщика удостоверений (IdP):
curl 'https://your-idp.com/.well-known/openid-configuration'
| jq .device_authorization_endpoint
https://your-idp.com/oauth2/v1/device/authorize
После запроса на device authorization endpoint IdP сгенерирует код устройства вместе с проверочной ссылкой для подтверждения его аутентификации. Эта ссылка будет передана на устройство.
С этого момента устройство начинает одновременно:
Посылать запросы с кодом устройства на соответствующий endpoint с целью обменять его на токен;
Выводить на экран проверочную ссылку.
После того как пользователь нажмет на проверочную ссылку, устройство получит токен.

Плюсы:
Класс! Можно аутентифицировать устройства!
Минусы:
Отныне вам придется покупать исключительно дорогую «умную» бытовую технику.
В этой статье кратко рассмотрены наиболее распространенные гранты OIDC и типичные сценарии их применения.
TLDR: в 99% случаев достаточно гранта Authorization Code, дополненного PKCE и refresh-токенами.
Расширяемость протокола OIDC позволяет изобретать кастомные гранты и декларировать их поддержку при обращении на discovery endpoint. Я умышленно обошел вниманием CIBA [8] – это интересный, многообещающий, но довольно «сырой» грант, который пока не поддерживается популярными провайдерами OIDC, такими как Okta или Auth0.
Надеюсь, эта статья помогла вам лучше понять процесс аутентификации в целом и процедуру получения токена в частности. Оставайтесь на связи!
Эта же статья доступна и на английском языке в блоге Flant [9]. Там же можно подписаться на технические материалы от наших инженеров, которыми легко делиться с ИТ-коллегами со всего мира.
Читайте также в нашем блоге:
Автор: Набоких Максим
Источник [13]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/informatsionnaya-bezopasnost/376042
Ссылки в тексте:
[1] спецификации OAuth2: https://datatracker.ietf.org/doc/html/rfc8693/
[2] по коду авторизации: https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.1
[3] PKCE: https://datatracker.ietf.org/doc/html/rfc7636
[4] Этот грант: https://datatracker.ietf.org/doc/html/rfc6749#section-4.2
[5] может предоставить: https://datatracker.ietf.org/doc/html/rfc6749#section-4.3
[6] не рекомендуется: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-13#section-3.4
[7] Этот грант: https://datatracker.ietf.org/doc/html/rfc6749#section-4.4
[8] CIBA: https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4
[9] в блоге Flant: https://blog.flant.com/oidc-grants-how-to-get-a-token/
[10] «Иллюстрированное руководство по OAuth и OpenID Connect»: https://habr.com/ru/company/flant/blog/475942/
[11] «Азбука безопасности в Kubernetes: аутентификация, авторизация, аудит»: https://habr.com/ru/company/flant/blog/468679/
[12] «Пользователи и авторизация RBAC в Kubernetes»: https://habr.com/ru/company/flant/blog/470503/
[13] Источник: https://habr.com/ru/post/670628/?utm_source=habrahabr&utm_medium=rss&utm_campaign=670628
Нажмите здесь для печати.