Авторизация через oauth что это
OAuth 2.0 простым и понятным языком
На хабре уже писали про OAuth 1.0, но понятного объяснения того, что такое OAuth 2.0 не было. Ниже я расскажу, в чем отличия и преимущества OAuth 2.0 и, как его лучше использовать на сайтах, в мобильных и desktop-приложениях.
Что такое OAuth 2.0
OAuth 2.0 — протокол авторизации, позволяющий выдать одному сервису (приложению) права на доступ к ресурсам пользователя на другом сервисе. Протокол избавляет от необходимости доверять приложению логин и пароль, а также позволяет выдавать ограниченный набор прав, а не все сразу.
Чем отличаются OpenID и OAuth
Не смотря на то, что объяснений на эту тему уже было много, она по-прежнему вызывает некоторое непонимание.
OpenID предназначен для аутентификации — то есть для того, чтобы понять, что этот конкретный пользователь является тем, кем представляется. Например, с помощью OpenID некий сервис Ололо может понять, что зашедший туда пользователь, это именно Рома Новиков с Mail.Ru. При следующей аутентификации Ололо сможет его опять узнать и понять, что, это тот же Рома, что и в прошлый раз.
OAuth же является протоколом авторизации, то есть позволяет выдать права на действия, которые сам Ололо сможет производить в Mail.Ru от лица Ромы. При этом Рома после авторизации может вообще не участвовать в процессе выполнения действий, например, Ололо сможет самостоятельно заливать фотографии на Ромин аккаунт.
Как работает OAuth 2.0
Как и первая версия, OAuth 2.0 основан на использовании базовых веб-технологий: HTTP-запросах, редиректах и т. п. Поэтому использование OAuth возможно на любой платформе с доступом к интернету и браузеру: на сайтах, в мобильных и desktop-приложениях, плагинах для браузеров…
Ключевое отличие от OAuth 1.0 — простота. В новой версии нет громоздких схем подписи, сокращено количество запросов, необходимых для авторизации.
Авторизация для приложений, имеющих серверную часть
Пример
Здесь и далее примеры приводятся для API Mail.Ru, но логика одинаковая для всех сервисов, меняются только адреса страниц авторизации. Обратите внимание, что запросы надо делать по HTTPS.
Редиректим браузер пользователя на страницу авторизации:
Здесь и далее, client_id и client_secret — значения, полученные при регистрации приложения на платформе.
После того, как пользователь выдаст права, происходит редирект на указанный redirect_uri:
Обратите внимание, если вы реализуете логин на сайте с помощью OAuth, то рекомендуется в redirect_uri добавлять уникальный для каждого пользователя идентификатор для предотвращения CSRF-атак (в примере это 123). При получении кода надо проверить, что этот идентификатор не изменился и соответствует текущему пользователю.
Используем полученный code для получения access_token, выполняя запрос с сервера:
Обратите внимание, что в последнем запросе используется client_secret, который в данном случае хранится на сервере приложения, и подтверждает, что запрос не подделан.
В результате последнего запроса получаем сам ключ доступа (access_token), время его «протухания» (expires_in), тип ключа, определяющий как его надо использовать, (token_type) и refresh_token о котором будет подробнее сказано ниже. Дальше, полученные данные можно использовать для доступа к защищенным ресурсам, например, API Mail.Ru:
Авторизация полностью клиентских приложений
Пример
Открываем браузер со страницей авторизации:
После того, как пользователь выдаст права, происходит редирект на стандартную страницу-заглушку, для Mail.Ru это connect.mail.ru/oauth/success.html:
Приложение должно перехватить последний редирект, получить из адреса acess_token и использовать его для обращения к защищенным ресурсам.
Авторизация по логину и паролю
Авторизация по логину и паролю представляет простой POST-запрос, в результате которого возвращается access token. Такая схема не представляет из себя ничего нового, но вставлена в стандарт для общности и рекомендуется к применению только, когда другие варианты авторизации не доступны.
Пример
Восстановление предыдущей авторизации
Обычно, access token имеет ограниченный срок годности. Это может быть полезно, например, если он передается по открытым каналам. Чтобы не заставлять пользователя проходить авторизацию после истечения срока действия access token‘а, во всех перечисленных выше вариантах, в дополнение к access token‘у может возвращаться еще refresh token. По нему можно получить access token с помощью HTTP-запроса, аналогично авторизации по логину и паролю.
Пример
Минусы OAuth 2.0
Во всей этой красоте есть и ложка дегтя, куда без нее?
OAuth 2.0 — развивающийся стандарт. Это значит, что спецификация еще не устоялась и постоянно меняется, иногда довольно заметно. Так, что если вы решили поддержать стандарт прямо сейчас, приготовьтесь к тому, что его поддержку придется подпиливать по мере изменения спецификации. С другой стороны, это также значит, что вы можете поучаствовать в процессе написания стандарта и внести в него свои идеи.
Безопасность OAuth 2.0 во многом основана на SSL. Это сильно упрощает жизнь разработчикам, но требует дополнительных вычислительных ресурсов и администрирования. Это может быть существенным вопросом в высоко нагруженных проектах.
Заключение
OAuth — простой стандарт авторизации, основанный на базовых принципах интернета, что делает возможным применение авторизации практически на любой платформе. Стандарт имеет поддержку крупнейших площадок и очевидно, что его популярность будет только расти. Если вы задумались об API для вашего сервиса, то авторизация с использованием OAuth 2.0 — хороший выбор.
Современные стандарты идентификации: OAuth 2.0, OpenID Connect, WebAuthn
Пускать или не пускать? Вот в чем вопрос…
Сейчас на многих сайтах мы видим возможность зарегистрироваться или войти с помощью соцсетей, а некоторые сайты предлагают использовать внешние ключи безопасности или отпечатки пальцев. Что это? Стандарты с хорошо проработанной безопасностью или проприетарные реализации? Можем ли мы доверять этим технологиям и использовать их для разработки сайтов и в повседневной жизни? Давайте разбираться. Итак, сейчас существуют несколько стандартов и технологий для идентификации пользователей OAuth 2.0,OpenID Connect, WebAuthn, SAML 2.0, Credential Management API и др. В статье я расскажу о трех наиболее перспективных протоколах OAuth 2.0, OpenID Connect и WebAuthn. И чтобы понять как их применять на практике, сделаем три лабораторные работы. В качестве платформ для идентификации пользователей будем использовать GitHub и Google, на которых у большинства есть аккаунты.
OAuth 2.0
Начнем с самого известного протокола OAuth 2.0. Он был опубликован в 2012 году, как RFC 6749: The OAuth 2.0 Authorization Framework.
С помощью OAuth 2.0 пользователь разрешает определенному сайту получить свои закрытые данные из соцсетей, но без передачи сайту своих логинов / паролей. Например, когда вы регистрируетесь на сайте через Facebook, то как раз и предоставляете этому сайту разрешение получить из Facebook ваше имя, e-mail адрес и другие закрытые данные.
Давайте разберемся с технической реализацией. Для простоты я буду называть любой сайт, который хранит идентификационные данные пользователя Соцсетью. А MySite буду называть любой сайт или приложение, которое хочет получить данные пользователя из Соцсети.
Стандарт определяет следующие роли:
Authorization flow
OAuth 2.0 Лабораторная работа (GitHub)
Существует множество инструкций, как реализовать OAuth 2.0 авторизацию, используя соцсети. Мне лично понравилась следующая статья: Authentication using GitHub OAuth 2.0 with NodeJS В ней подробно описаны шаги и приведена тестовая программа. Но, чтобы действительно осознать алгоритм, лучше пройти все шаги руками (http запросами из браузера или вызовами curl). Поехали.
Для начала регистрируем свое приложение на GitHub: github.com/settings/applications/new
Получаем от GitHub:
Так выглядит получение Client ID и Secret на сайте GitHub:
Теперь начинаем авторизацию. Считаем, что Шаг 1 уже пройден: пользователь зашел на MySite и выбрал “Войти с помощью GitHub ”. Шаг 2 из call flow — это вызов в REST формате:
Шаг 3: Вводим логин/пароль для доступа на GitHub
Шаг 4: GitHub перенаправляет запрос на Homepage, в этом запросе мы видим code:
По данному адресу нет работающего сайта, но для нас главное знать присланный code, чтобы сформировать следующий Шаг 5:
Шаг 7: Вставляем access_token в заголовок запроса и вызоваем GitHub API:
Шаг 8: В ответ получаем JSON с полезной информацией обо мне, которую можно использовать для формирования профиля на MySite:
На самой деле, мы рассмотрели только один сценарий работы OAuth 2.0. Существует несколько сценариев, каждый из которых используется в зависимости от приложения, соображений безопасности, способу развертывания и т.д. Описание всех сценариев можно найти, например, тут: OAuth 2.0 in a Nutshell.
OpenID Connect
С OAuth 2.0 немного разобрались. Теперь выясним зачем нужен OpenID Connect, который является надстройкой над OAuth 2.0:
OpenID Connect (OIDC) — открытый стандарта OpenID, который разрабатывает консорциум OpenID Foundation. OIDC расширяет OAuth 2.0 следующими основными возможностями:
OpenID Connect: Лабораторная работа (Google)
Теперь посмотрим, чем нас по данной теме порадует Google. Есть подробная инструкция по конфигурации и использованию OpenID Connect от Google и “песочница” по использованию Google API: Google OAuth 2.0 Playground.
Здесь, как и в случае с OAuth 2.0, мы пройдем путь по шагам и посмотрим на приходящие данные. Аналогично считаем, что приложение зарегистрировано, Client ID и Client Secret получены, Шаг 1 пройден. Шаг 2 из call flow — это вызов в REST формате:
У Google немного посложнее, т.к. безопасности они уделяют больше внимания:
Шаг 4: Google перенаправляет запрос на Homepage, в этом запросе мы видим code:
Также как и в случае с GitHub по данному адресу нет работающего сайта, но это и не надо, нам главное знать code, чтобы сформировать следующий Шаг 5. Тут тоже немного посложнее, т.к. Google требует запрос POST, а не GET:
Что теперь делать с этим богатством?
Шаг 7: C access_token все понятно: включаем его в вызов API, например GMail:
Шаг 8: В ответ получаем JSON с полезной информацией:
Теперь давайте проверим утверждение, что в id_token содержится информация для аутентификации пользователя и поддержания сессии. Для этого надо расшифровать содержимое. Самый простой способ сделать это, обратиться к Google API по адресу
oauth2.googleapis.com/tokeninfo и в качестве параметра указать полученный id_token:
Видим, что в id_token содержится информация о логине пользователя, времени получения и времени жизни токена. Можно сделать вывод, что OpenID Connect от Google работает, и его можно применять для соответствующих сценариев.
WebAuthn
По сравнению с OAuth 2.0 в WebAuthn добавляются роли:
Authenticator: внешний ключ безопасности (физический носитель или сканер отпечатков пальцев), который позволяет аутентифицировать пользователя, использую различные технологии, такие как BlueTooth/NFC/USB. Служит для:
Relying Party: выполняет ту же функцию, что и “Authorization Server” в OAuth 2.0, а именно проверяет идентификационные данные пользователя. Только в OAuth 2.0 это были логин/пароль, а в WenAuthn — public key credentials.
User Agent: объединяет браузер и сетевое приложение, служит для тех же целей, что и Client в OAuth 2.0, а именно — с одной стороны взаимодействует с пользователем и предоставляет ему GUI, а с другой стороны взаимодействует с системами, в которых хранятся идентификационные данные пользователя.
Authorization flow
Перед началом процесса аутентификации, также как и в OAuth 2.0, надо совершить подготовительные действия, только в OAuth 2.0 мы регистрировали приложение, а в WebAuth 2.0 регистрируем пользователя. В Web Authentication API специфицировано два вызова:
В результате этого в Authenticator-е пользователя сохранится закрытый ключ для определенного сайта, а в Relying Party сохранится открытый ключ.
После этого процесс аутентификации будет таким:
WebAuthn: Лабораторная работа (Google)
Для реализации WebAuthn только http запросами не обойтись, т.к. нужно вызывать браузерное API для взаимодействия с Authenticator-ом. Но и тут Google радует, сделали песочницу с пошаговой инструкцией: Your first WebAuthn.
В результате выполнения работы получится JS клиент-серверное приложение, которое реализует аутентификацию с помощью отпечатка пальца. Работающая дема находится по адресу.
Если ее запустить на смартфоне с датчиком отпечатков пальцев, то можно посмотреть результат работы. Как обычно, сначала подготовка — регистрируем пользователя:
Создаем логин / пароль и далее привязываем отпечаток пальца:
После этого программа показывает какой открытый ключ привязан к этому отпечатку:
Теперь можно начинать сценарий по аутентификации. Как обычно, считаем, что Шаг 1 пройден и мы находимся на сайте. Чтобы перейти к Шагу 2 надо нажать “Try Reauth”. Браузер выполнит Шаг 3 и вступит во взаимодействие с Authenticator-ом, который на Шаге 4 попросит приложить палец:
И если приложен зарегистрированный палец, то Шаги 5 и 6 успешно пройдут и на Шаге 7 приложение опять покажет окно с соответствующим открытым ключом:
Заключение
Итак, мы рассмотрели три наиболее распространенных и перспективных протокола для идентификации пользователей: OAuth 2.0, OpenID Connect, WebAuthn. Поняли области их применимости:
Выводы
Приложение: остальные протоколы идентификации
Для полноты картины перечислю остальные актуальные протоколы и технологии, используемые для идентификации пользователей:
SAML 2.0 (Security Assertion Markup Language)
Зрелый протокол 2005 года, но имеет ограниченный набор сценариев для построения систем SSO. Использует формат данных на основе XML. Подробнее можно посмотреть в статье: “Кто использует протокол аутентификации SAML 2.0”
Credential Management API
Разработкой занимается та же организация, что и WebAuthn — W3C. Стандарт Credential Management позволяет:
Иллюстрированное руководство по OAuth и OpenID Connect
Прим. перев.: В этом замечательном материале компании Okta просто и наглядно рассказывается о принципах работы OAuth и OIDC (OpenID Connect). Эти знания будут полезны разработчикам, системным администраторам и даже «обычным пользователям» популярных веб-приложений, которые скорее всего тоже обмениваются конфиденциальными данными с другими сервисами.
В «каменном веке» интернета делиться информацией между сервисами было легко. Вы просто давали свой логин и пароль от одного сервиса другому, чтобы тот вошел в вашу учетную запись и получил любую необходимую ему информацию.
«Предоставьте свою банковскую учётку». — «Обещаем, что с паролем и деньгами все будет в порядке. Вот прям честно-пречестно!» *хи-хи*
Жуть! Никто и никогда не должен требовать от пользователя поделиться логином и паролем, его учётными данными, с другим сервисом. Нет никакой гарантии, что организация, стоящая за этим сервисом, будет хранить данные в безопасности и не соберет больше персональной информации, чем нужно. Это может показаться дикостью, но некоторые приложения до сих пор применяют подобную практику!
Сегодня имеется единый стандарт, позволяющий одному сервису безопасно воспользоваться данными другого. К сожалению, подобные стандарты используют массу жаргонизмов и терминов, что усложняет их понимание. Цель этого материала — с помощью простых иллюстраций объяснить, как они работают (Думаете, что мои рисунки напоминают детскую мазню? Ну и ладно!).
Между прочим, это руководство также доступно в формате видео:
Дамы и господа, встречайте: OAuth 2.0
OAuth 2.0 — это стандарт безопасности, позволяющий одному приложению получить разрешение на доступ к информации в другом приложении. Последовательность действий для выдачи разрешения [permission] (или согласия [consent]) часто называют авторизацией [authorization] или даже делегированной авторизацией [delegated authorization]. С помощью этого стандарта вы позволяете приложению считать данные или использовать функции другого приложения от вашего имени, не сообщая ему свой пароль. Класс!
В качестве примера представим, что вы обнаружили сайт с названием «Неудачный каламбур дня» [Terrible Pun of the Day] и решили зарегистрироваться на нем, чтобы ежедневно получать каламбуры в виде текстовых сообщений на телефон. Сайт вам очень понравился, и вы решили поделиться им со всеми знакомыми. Ведь жуткие каламбурчики нравятся всем, не так ли?
«Неудачный каламбур дня: Слышали о парне, который потерял левую половину тела? Теперь он всегда прав!» (перевод примерный, т.к. в оригинале своя игра слов — прим. перев.)
Понятно, что писать каждому человеку из контакт-листа не вариант. И, если вы хотя бы чуточку похожи на меня, то пойдете на всё, чтобы избежать лишней работы. Благо Terrible Pun of the Day может сам пригласить всех ваших друзей! Для этого лишь нужно открыть ему доступ к электронной почте контактов — сайт сам отправит им приглашения (OAuth рулит)!
«Все любят каламбуры! — Уже залогинились? — Хотите открыть доступ сайту Terrible Pun of the Day к списку контактов? — Спасибо! Теперь мы каждый день будем слать напоминания всем, кого вы знаете, до скончания веков! Вы самый лучший друг!»
Поток OAuth
Только что мы прошли через то, что обычно называют потоком [flow] OAuth. В нашем примере этот поток состоит из видимых шагов, а также из нескольких невидимых шагов, в рамках которых два сервиса договариваются о безопасном обмене информацией. В предыдущем примере с Terrible Pun of the Day используется наиболее распространенный поток OAuth 2.0, известный как поток «с кодом авторизации» [«authorization code» flow].
Прежде чем углубиться в подробности работы OAuth, давайте поговорим о значении некоторых терминов:
Ключ, который клиент будет использовать для связи с Resource Server‘ом. Этакий бейдж или ключ-карта, предоставляющий Client‘у разрешения на запрос данных или выполнение действий на Resource Server‘е от вашего имени.
Примечание: иногда Authorization Server и Resource Server являются одним и тем же сервером. Однако в некоторых случаях это могут быть разные серверы, даже не принадлежащие к одной организации. Например, Authorization Server может быть сторонним сервисом, которому доверяет Resource Server.
Теперь, когда мы ознакомились с основными понятиями OAuth 2.0, давайте вернемся к нашему примеру и подробно рассмотрим, что происходит в потоке OAuth.
Client ID и Secret
Задолго до того, как вы разрешили Terrible Pun of the Day получить доступ к контактам, Client и Authorization Server установили рабочие отношения. Authorization Server сгенерировал Client ID и Client Secret (иногда их называют App ID и App Secret) и отправил их Client’у для дальнейшего взаимодействия в рамках OAuth.
«— Привет! Я хотел бы работать с тобой! — Да не вопрос! Вот твои Client ID и Secret!»
Название намекает, что Client Secret должен держаться в тайне, чтобы его знали только Client и Authorization Server. Ведь именно с его помощь Authorization Server подтверждает истинность Client’а.
Но это ещё не всё… Пожалуйста, поприветствуйте OpenID Connect!
OAuth 2.0 разработан только для авторизации — для предоставления доступа к данным и функциям от одного приложения другому. OpenID Connect (OIDC) — это тонкий слой поверх OAuth 2.0, добавляющий сведения о логине и профиле пользователя, который вошел в учетную запись. Организацию логин-сессии часто называют аутентификацией [authentication], а информацию о пользователе, вошедшем в систему (т.е. о Resource Owner‘е), — личными данными [identity]. Если Authorization Server поддерживает OIDC, его иногда называют поставщиком личных данных [identity provider], поскольку он предоставляет Client‘у информацию о Resource Owner‘е.
OpenID Connect позволяет реализовывать сценарии, когда единственный логин можно использовать во множестве приложений, — этот подход также известен как single sign-on (SSO). Например, приложение может поддерживать SSO-интеграцию с социальными сетями, такими как Facebook или Twitter, позволяя пользователям использовать учётную запись, которая у них уже имеется и которую они предпочитают использовать.
Так же, как и в потоке OAuth, Access Token в OpenID Connect — это некое значение, не понятное Client‘у. С точки зрения Client‘а Access Token представляет некую строку из символов, которая передается вместе с каждым запросом к Resource Server‘у, а тот определяет, действителен ли токен. ID Token представляет собой совсем иное.
ID Token — это JWT
ID Token — это особым образом отформатированная строка символов, известная как JSON Web Token или JWT (иногда токены JWT произносят как «jots»). Сторонним наблюдателям JWT может показаться непонятной абракадаброй, однако Client может извлечь из JWT различную информацию, такую как ID, имя пользователя, время входа в учетную запись, срок окончания действия ID Token‘а, наличие попыток вмешательства в JWT. Данные внутри ID Token‘а называются заявками [claims].
В случае OIDC также имеется стандартный способ, с помощью которого Client может запросить дополнительную информацию о личности [identity] от Authorization Server‘а, например, адрес электронной почты, используя Access Token.
Дополнительные сведения об OAuth и OIDC
Итак, мы вкратце рассмотрели принципы работы OAuth и OIDC. Готовы копнуть глубже? Вот дополнительные ресурсы, которые помогут узнать больше об OAuth 2.0 и OpenID Connect: