Статьи

OAuth 2.0 — Хороший, плохой и уродливый

В мире, где доминируют социальные сети, трудно не встретить клиентское приложение, которое вы использовали для доступа к ограниченным ресурсам на каком-либо другом сервере, например, вы могли бы использовать веб-приложение (например, NY Times) для обмена Интересная новостная статья на вашей стене Facebook или твит об этом. Или вы могли использовать приложение Quora для iPhone, которое обращается к вашему профилю в Facebook или Google+ и настраивает результаты на основе данных вашего профиля, например, предлагая добавить / пригласить других пользователей в Quora на основе вашего списка друзей. Вопрос в том, как эти приложения получают доступ к вашим учетным записям Facebook, Twitter или Google+ и как они могут получить доступ к вашим конфиденциальным данным? Прежде чем они смогут это сделать, они должны представить учетные данные и полномочия для авторизации на сервере ресурсов.


OAuth часто описывается как ключ камердинера для Интернета.

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

Однако OAuth — это не новая концепция, а стандартизация и объединенная мудрость многих устоявшихся протоколов. Также стоит отметить, что OAuth не ограничивается только приложениями социальных сетей, но предоставляет стандартизированный способ безопасного обмена информацией между различными типами приложений, которые предоставляют свои API-интерфейсы другим приложениям. OAuth 2.0 имеет совершенно новую прозу и не имеет обратной совместимости со своими предшественниками. Сказав это, было бы хорошо, чтобы сначала охватить некоторый базовый словарь OAuth2.0, прежде чем углубляться в дальнейшие детали.

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

Основным недостатком OAuth 1.0 была внутренняя сложность, необходимая для реализации спецификации.

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

  • Подписание каждого запроса. То, что клиент генерирует подписи для каждого запроса API и проверяет их на сервере при каждом получении запроса, оказалось серьезным препятствием для разработчиков, поскольку ему приходилось анализировать, кодировать и сортировать параметры перед выполнением запроса. OAuth 2.0 устраняет эту сложность, просто отправляя токены по SSL, решая ту же проблему на сетевом уровне. С OAuth 2.0 подписи не требуются.
  • Обращение к собственным приложениям . С развитием собственных приложений для мобильных устройств веб-интерфейс OAuth 1.0 казался неэффективным, требуя использования пользовательских агентов, таких как веб-браузер. OAuth 2.0 поддерживает больше потоков, особенно подходящих для нативных приложений.
  • Четкое разделение ролей : OAuth 2.0 обеспечивает столь необходимое разделение ролей для сервера авторизации, выполняющего аутентификацию и авторизацию клиента, и для сервера ресурсов, обрабатывающего вызовы API для доступа к ограниченным ресурсам.

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

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

  • Поток User-Agent : Подходит для клиентов, обычно реализуемых в пользовательских агентах (например, клиенты, работающие в веб-браузере) с использованием языка сценариев, такого как JavaScript. В основном используется нативными приложениями для мобильных или настольных компьютеров, используя встроенный или внешний браузер в качестве пользовательского агента для авторизации, и он использует авторизацию Implicit Grant .
  • Поток веб-сервера : он использует грант кода авторизации и представляет собой поток на основе перенаправления, который требует взаимодействия с пользовательским агентом конечного пользователя. Таким образом, он наиболее подходит для клиентов, которые являются частью приложений на основе веб-сервера, к которым обычно обращаются через веб-браузер.
  • Имя пользователя и поток паролей : используется только в том случае, если между клиентом и владельцем ресурса существует высокое доверие, а другие потоки нежизнеспособны, поскольку это связано с передачей учетных данных владельца ресурса. Примерами клиентов могут быть операционная система устройства или приложение с высокими привилегиями. Это также можно использовать для миграции существующих клиентов с использованием схем HTTP Basic или Digest Authentication в OAuth путем преобразования сохраненных учетных данных в токен доступа.
  • Поток подтверждений: ваш клиент может представить утверждение, такое как подтверждение SAML, серверу авторизации в обмен на токен доступа.
  • Поток учетных данных клиента : OAuth в основном используется для делегированного доступа, но бывают случаи, когда клиенту принадлежит ресурс или ему уже предоставлен делегированный доступ за пределами типичного потока OAuth. Здесь вы просто обмениваете учетные данные клиента на токен доступа.

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

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

webserverflow

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

step1Request

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

разрешить доступ

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

step1Response

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

step2Request

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

step2Response

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

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

Обратите внимание, что мы добавили токен доступа в качестве заголовка авторизации в запрос, а также экранировали токен, включив его в одинарные кавычки, так как токен может содержать специальные символы. Имейте в виду, что экранирование токена доступа требуется только при использовании curl. Это приводит к отправке следующего запроса:

step3Request

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

step3Response

Эти примеры любезно предоставлены OAuth2.0 Playground и типичны для того, как Google реализует спецификацию. Различия могут наблюдаться при попытке того же потока с другими провайдерами (например, Facebook или Salesforce), и именно здесь возникают проблемы совместимости, которые мы обсудим чуть позже.

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

step4Request

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

step4Response

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


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

В спецификации есть несколько слабых сторон, так как не удается правильно определить несколько обязательных компонентов или оставить их на усмотрение реализаций, таких как:

Свободные концы в спецификации OAuth 2.0, вероятно, приведут к широкому спектру не совместимых реализаций.

  • Функциональная совместимость : добавление слишком большого количества точек расширения в спецификацию привело к реализациям, которые несовместимы друг с другом. Это означает, что вы не можете надеяться написать общий фрагмент кода, который использует Endpoint Discovery, чтобы узнать о конечных точках, предоставленных различными реализациями. и взаимодействовать с ними, скорее вам придется написать отдельные кусочки кода для Facebook, Google, Salesforce и так далее. Даже спецификация признает этот отказ в качестве отказа от ответственности.
  • Короткоживущие токены : спецификация не требует срока действия и объема выданных токенов. Реализация бесплатна, чтобы токен жил вечно. Хотя большинство реализаций предоставляют нам краткосрочные токены доступа и токен обновления, которые можно использовать для получения нового токена доступа.
  • Безопасность : спецификация просто «рекомендует» использовать SSL / TLS при отправке токенов в виде открытого текста по проводам. Хотя в каждой крупной реализации требовалось, чтобы конечные точки безопасной авторизации также требовали, чтобы у клиента был защищенный URL-адрес перенаправления, иначе злоумышленнику будет слишком легко подслушивать сообщения и расшифровывать токены.

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


Спецификация, безусловно, оставляет открытыми многие точки расширения, что приводит к реализациям, которые вводят свои собственные параметры в дополнение к тому, что спецификация уже определяет, и гарантирует, что реализации от разных поставщиков не могут взаимодействовать друг с другом. Но, учитывая популярность и скорость принятия этой платформы, поскольку каждый крупный игрок в городе (Google, Twitter, Facebook, Salesforce, Foursquare, Github и т. Д.) Внедряет и настраивает его так, как ему удобно, OAuth далеко не провал. , Фактически, любое веб-приложение, которое планирует представить свои API-интерфейсы другим веб-приложениям, должно поддерживать некоторую форму аутентификации и авторизации, и OAuth отвечает всем требованиям.