OAuth 2.0 – хороший, плохой, злой…

В мире, где все доминируют социальные медиа, трудно не поддаться искушению установить клиентское приложение, с помощью которого вы смогли бы получить доступ к ограниченным ресурсам на другом сервере.

Например, вы могли бы использовать веб-приложение (скажем, от Нью-Йорк Таймс) для импорта интересных статей в ваш Facebook или Твиттер. Или вы могли бы использовать приложение для iPhone Quora, с помощью которого пользователи могут получать доступ к доске ваших новостей на том же Facebook или Google+.

Его можно настроить с учетом данных вашего профиля: добавлять / приглашать к Quora пользователей, которые находятся в вашем списке друзей. Вопрос в том, как эти приложения получают доступ к вашему аккаунту Facebook, Twitter или Google+, а особенно к конфиденциальной информации?

Прежде чем приложение сможет это сделать, оно должно предоставить некую форму грантов аутентификации и авторизации ресурсам сервера.

Введение в OAuth 2.0

На сегодняшний день это действительно круто иметь возможность поделиться своими записями из Facebook или Google+ с любым сторонним клиентским приложением. Причем сделать так, чтобы ваши записи были доступны только вашим друзьям, так как сервис не только ограничивает нежелательный доступ, но и отслеживает пользователей, основываясь на логинах и паролях.

Здесь в игру и вступает OAuth, который является фреймворком для удаленного делегирования доступов / авторизации, который можно использовать без необходимости дополнительного обмена паролями. По этой причине OAuth часто называют камердинерской связкой ключей от Интернета.

Его можно рассматривать как особый ключ, который позволяет получить доступ к ограниченному набору функций, в течение определенного периода времени, при этом передавая приложению полный контроль.

Подобно тому, как парковщику позволяется припарковать машину у ресторана, но при этом ему не разрешено ездить на ней по городу, пользоваться встроенным мобильным телефоном или другими функциями.

Тем не менее, OAuth не базируется на какой-то абсолютно новой технологии, но умно использует комбинацию стандартных, давно установленных протоколов.

Также стоит отметить, что OAuth не ограничивается только социальными медиа - он обеспечивает формализованный надежный способ обмена информацией между различными видами приложений, которые предоставляют ограниченный доступ к своим функциям.

OAuth 2.0 имеет совершенно новую идеологию и поддерживает обратную совместимость с приложениями предыдущих версий. Прежде чем пояснить, в чем его преимущества, я хотел бы сначала, рассмотреть определения некоторых понятий и функций, которыми оперирует, OAuth2.0:

  • Ресурс владельца: приложение, которое способно предоставлять доступ к защищенному ресурсу. Как правило, конечным пользователям;
  • Клиент: приложение, которое отправляет запросы к защищенному ресурсу от имени его владельца и с его разрешения. Это могут быть серверные, мобильные или настольные приложения;
  • Сервер ресурса: сервер защищенного ресурса, способный принимать и отвечать на запросы к ресурсу;
  • Авторизация на сервере: выдача сервером клиенту грантов / маркеров доступа после успешной аутентификации у ресурса владельца и получения от него разрешения;
  • Маркер доступа: маркеры доступа к учетным данным, которые клиент предоставляет серверу ресурса для получения возможности использовать защищенные ресурсы. Обычно это строка параметров, определяющих границы доступа, продолжительности сессии и другие атрибуты. Она также может содержать данные для прохождения авторизации в той или иной форме;
  • Обновление маркера: Хотя это и не предусмотрено по умолчанию, маркеры доступа в идеале должны иметь срок действия (сессии), который может составлять от нескольких минут до нескольких часов. Как только время действия маркера доступа истекло, клиент может запросить сервер об авторизации и выдаче нового маркера доступа с помощью обновления маркера.

В чем была проблема OAuth 1.0?

Главным недостатком OAuth 1.0 была слишком большая сложность данной версии.

На самом деле никаких особых проблем не было! Twitter по-прежнему отлично работает с OAuth 1.0 и просто добавил еще и поддержку версии 2.0. OAuth 1.0 был хорошо продуманной версией фреймворка, которая обеспечивала надежный обмен закрытой информацией, и это делало возможным обмен секретной информацией без подключения SSL.

Причина, почему потребовалась разработка обновления заключается в основном в сложности, с которой была сопряжена работа версии. Ниже приведены некоторые сферы, где OAuth 1.0 не отвечал всем современным требованиям:

  • Подпись каждого запроса: Наличие клиентов, которые генерировали подписи каждого запроса приложений и проверяли на сервере каждый запрос. Это стало серьезным ударом для разработчиков, которые должны были разбирать, кодировать и сортировать параметры, прежде чем отправить запрос.

    В OAuth 2.0 удалось эту сложность обойти. Просто отсылая маркеры по SSL и решая эту задачу на сетевом уровне. OAuth 2.0 не требуется никаких сигнатур;

  • Переадресация встроенных приложений: С развитием встроенных приложений браузеров для мобильных устройств веб-потоки OAuth 1.0 оказались просто неэффективны.

    Так, для них обязательно использование таких агентов как сам интернет-браузер. В OAuth 2.0 потоки были переориентированы именно на работу с встроенными приложениями;

  • Четкое разделение ролей: OAuth 2.0 обеспечивает столь необходимое разделение ролей для сервера авторизации, аутентификации и авторизации клиента, с помощью чего сервер ресурса может обрабатывать запросы приложений на предоставление доступа к закрытым ресурсам.

OAuth 2.0 в деталях

Перед инициализацией протокола клиент должен зарегистрироваться на сервере авторизации, предоставляя информацию о типе клиента, URL-адресе перенаправления (куда он должен быть перенаправлен для авторизации, после того, как сервер ресурса выдаст ему грант или же откажет в доступе) и любую другую информацию, необходимую серверу.

Взамен он получает идентификатор клиента (client_id) и секретный код клиента (client_secret). Этот процесс называется регистрацией клиента. После регистрации клиент может взаимодействовать с сервером по одному из следующих потоков.

Возможные потоки OAuth

OAuth 2.0 добавляет в таблицу порядка пяти новых потоков, что обеспечивает разработчикам гибкость в реализации решений. Они могут использовать любой из них, в зависимости от типа клиента, задействованного в процессе обмена данными:

  • Поток пользователь-агент: Как правило, подходит для клиентов, реализованных на базе приложений-агентов пользователей (например, клиенты, запускаемые внутри оболочки веб-браузера) с помощью языков сценариев, таких как JavaScript и другие.

    В основном используется встроенными приложениями для мобильных устройств или операционных систем. В качестве агента пользователя авторизации использует встроенный или внешний браузер, который поддерживает Implicit Grant авторизацию;

  • Поток веб-сервера: Обеспечивает использование гранта кода авторизации. Он представляет собой поток, основанный на принципе перенаправлений, для которого необходимо взаимодействие с агентом конечного пользователя.

    Таким образом, данный поток подходит для клиентов, которые являются частью приложений, работающих на сервере, доступ к которым, как правило, осуществляется через веб-браузер;

  • Поток имен пользователей и паролей: Используется только в случае, когда наличествует высокая степень доверия между клиентом и ресурсом владельца, в то время как прочие потоки не в состоянии решить поставленную задачу. Он предполагает передачу клиенту полномочий владельца ресурса.

    В качестве примера клиента для такого рода взаимодействий можно привести операционную систему устройства или приложение с обширными правами доступа. Он также может использоваться для переноса существующих клиентов через протокол HTTP или схемы Digest Authentication в OAuth путем преобразования записанных учетных данных в маркер доступа;

  • Поток утверждения: Ваш клиент может выдавать утверждение, например SAML утверждения, взамен на предоставленный маркер доступа;
  • Поток идентификационной информации клиента: OAuth используется в основном для делегированного доступа, но бывают случаи, когда клиент является одновременно и владельцем ресурса или уже ему были предоставлены права доступа сверх обычных потоков OAuth . Здесь просто происходит обмен предоставленных идентификационных данных клиента на маркер доступа.

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

Но чтобы дать вам больше базовых знаний для их изучения, давайте рассмотрим более глубоко один из наиболее часто используемых потоков: поток веб-сервера.

Поток веб-сервера

Так как данный поток использует перенаправления, клиент должен иметь возможность взаимодействовать с агентом пользователя владельца ресурса (в качестве которого в большинстве случаев выступает веб-браузер) и, следовательно, он подходит для работы с веб-приложениями.

На диаграмме ниже, в общем, показано, как конечный пользователь (или владелец ресурса) использует клиентское приложение (в данном случае на основе приложения сервера) для аутентификации и авторизации на сервере, для того, чтобы получить доступ к защищенным ресурсам.

Поток веб-сервера

Аутентификация и авторизация клиента

Клиент от имени владельца ресурса инициирует поток путем перенаправления к конечной точке авторизации, используя при этом: параметр response_type в качестве кода; идентификатор клиента, который был получен в процессе регистрации клиента; URL-адрес перенаправления; запрошенный объем полномочий (опционально) и текущее состояние (если требуется).

Чтобы получить более наглядное представление о том, как осуществляется весь процесс, на скриншоте ниже графически представлено, как будет выглядеть обработка стандартного запроса / ответа:

Аутентификация и авторизация клиента

Через веб-интерфейс владельцу ресурса обычно представляется следующая панель, в которой он может удостовериться в том, что все разрешения клиентским приложением получены, и оно может использовать закрытые ресурсы от имени их владельца.

Аутентификация и авторизация клиента - 2

Если, клиентом получены гранты владельца ресурса на доступ, сервер авторизации перенаправляет агент пользователя обратно клиенту с помощью параметров перенаправления, которые были предоставлены ранее, вместе с кодом авторизации.

Как это показано на рисунке ниже:

Обмен кода авторизации на маркер

После этого клиент переходит на следующий этап и отправляет код авторизации, полученный на предыдущем этапе вместе с URL-адресом перенаправления, идентификатором клиента, секретным кодом, полученным в процессе регистрации клиента, и параметром grant_type, который должен быть установлен как authorization_code.

Обмен кода авторизации на маркер

Затем сервер проверяет код авторизации и URL-адрес перенаправления, так же, как на предыдущем этапе. В случае успешного прохождения проверки, сервер направляет ответ вместе с маркером доступа и, опционально, с обновленным маркером.

Обмен кода авторизации на маркер - 2

Запрос на получение доступа к закрытым ресурсам с использованием маркеров доступа.

Теперь клиент может использовать приложения, предоставляемые сервером, а также направлять запросы на использование закрытых ресурсов.

При этом в заголовке Authorization запроса прилагается маркер доступа. В качестве примера CURL-запроса на получение в блог данных с Google Blogger API с учетом идентификатора может послужить следующий код:

$ curl https://www.googleapis.com/blogger/v3/blogs/5223788876950011016 -H 'Authorization: OAuth ya29.AHES6ZRTj1GNxAby81Es-p_YPWWNBAFRvBYVsYj2HZJfJHU'

Обратите внимание, что маркер доступа добавлен в качестве заголовка Authorization в запросе, а также выделен одинарными кавычками, так как маркер может содержать специальные символы.

Имейте в виду, что выделение маркера доступа требуется только при двустороннем взаимодействии. В результате чего отправляется запрос:

Затем сервер ресурса проверяет передаваемые данные (маркер доступа) и в случае успешной проверки, отправляет запрашиваемую информацию.

Данные примеры иллюстрируют принципы работы OAuth2.0 Playground. Подобным образом, как правило, реализуется взаимодействие данной версии с Google.

Немного по-другому взаимодействие может происходить при обращении к другим сервисам (к примеру, Facebook или Salesforce), что связано с проблемами слабой совместимости конечных решений, которые мы обсудим чуть позже.

Обновление маркера доступа

Хотя это и не предусмотрено по умолчанию, но, как правило, маркеры доступа имеют ограниченный срок действия. Поэтому, когда период действия маркера истек, клиент отсылает к серверу авторизации запрос на обновление маркера.

К нему прилагаются идентификатор клиента и секретный код, а также параметр grant_type в качестве refresh_token.

Обновление маркера доступа

В ответ сервер авторизации отправляет пакет с новым значением маркера.

Обновление маркера доступа - 2

Не смотря на то, что механизм отзыва обновленного маркера и существует, как правило, он хранится вечно, а потому должен быть защищен, точно так же, как и все секретные данные.

Так в чем же проблема OAuth 2.0?

Хороший (положительный момент).

Судя по скорости, с которой был выпущен OAuth 2.0, это, безусловно, шаг вперед по сравнению с его предшественником. Известны случаи, когда члены сообщества разработчиков имели некоторые затруднения при внедрении версии 1.0. OAuth 2.0 предоставляет несколько новых видов грантов, которые могут быть использованы для реализации различных задач пользователей, связанных с встроенными приложениями, однако главным плюсом этой версии фреймворка является его простота по сравнению версией 1.0.

Плохой (негативные моменты).

Неотточенные элементы версии OAuth 2.0 могут привести к тому, что большое количество решений по его внедрению будут несовместимы друг с другом.

В данной версии остаются несколько недоработанных моментов, связанных с тем, что она не может правильно определить несколько необходимых компонентов или взаимодействие с ними еще не прописано:

  • Взаимодействие: Добавление слишком большого количества обновлений и расширений привело к тому, что некоторые компоненты просто несовместимы друг с другом. Это значит, что вы не можете написать универсальный код с использованием Endpoint Discovery, и быть уверенным, что он подойдет для взаимодействия с различными сервисами.

    На самом деле вам придется писать отдельные фрагменты кода под Facebook, Google, Salesforce и так далее. Данный момент даже признан в спецификации версии;

  • Ограниченный срок действия маркеров: Данная версия фреймворка не обеспечивает бессрочный период действия всех маркеров, которые были выданы.

    Хотя в зависимости от конкретных практических решений такая возможность существует. В большинстве же случаев предоставляется краткосрочный маркер доступа с возможностью его обновления по запросу;

  • Безопасность: В данной версии всего лишь «рекомендовано» использование протоколов SSL / TLS при отправке маркеров в виде обычного текста по сети.

    Хотя, для каждого крупного решения обязательно иметь безопасные конечные точки авторизации, наличие для клиента безопасного URL-адреса перенаправления. В противном случае злоумышленникам будет слишком просто перехватить сообщения и расшифровать маркеры.

Злой…

Было перепробовано порядка 31 черновой версии фреймворка, в ходе чего также был смещен ведущий автор / разработчик Эран Хаммер, прежде чем новая версия, наконец, увидела свет. Эран настаивал на том, что в данной спецификации реализован «плохой протокол и она нежизнеспособна вследствие еще тысячи огрех».

По его словам, использование маркеров «на предъявителя» (отправка маркеров по SSL без подписи их или любой другой верификации) вместо сигнатур пользователей (или MAC-маркеров), которые использовались в OAuth 1.0 – это неудачное решение. Это, по его словам, результат предпочтения интересов предпринимателей интересам веб-сообщества.

Несколько замечаний в заключение

Данная версия, безусловно, оставляет открытыми много аспектов, и в зависимости от задач конкретных прикладных применений их авторы устанавливают свои собственные параметры, в дополнение к тому, что прописано во фреймворке.

Что не гарантирует того, что практические решения от различных провайдеров будут нормально взаимодействовать друг с другом.

Однако с каждым новым внедрением для больших сервисов (Google, Twitter, Facebook, Salesforce, Foursquare, Github и т.д.) OAuth становится все популярнее.

На самом деле, любой веб-сервис, который планирует предоставлять доступ к своим приложениям другим сервисам, должен поддерживать некую форму аутентификации и авторизации. И OAuth, отвечает этим требованиям.

РедакцияПеревод статьи «OAuth 2.0 – The Good,The Bad & The Ugly»