пятница, 30 августа 2013 г.

Что хорошего в OAuth 2.0



OAuth – это открытый протокол авторизации. Он позволяет клиенту получить доступ к ресурсам сервера от имени владельца этого ресурса. Также OAuth предоставляет возможность авторизации доступа из сторонних приложений без необходимости предоставления авторизационных данных (логина/пароля)
В наше время протокол является весьма популярным, так как он делает возможным для сторонних приложений получение доступных данных с серверов социальных сетей и сервисов.
Не так давно увидела свет новая версия протокола OAuth 2.0 которая сильно отличается от первой версии. Что же хорошего в этой версии попытаемся разобраться в данной публикации.
Предлагаю вашему вниманию перевод поста StackOverflow где затронут этот вопрос. Оригинал можно найти здесь: http://stackoverflow.com/questions/7561631/oauth-2-0-benefits-and-use-cases-why


Q:
Может ли кто объяснить чего хорошего в OAuth2 и почему мы должны его реализовывать? Я спрашиваю потому что я несколько смущен – и вот почему:
Запросы OAuth1 (или HMAC) кажутся логичными, понятными, простыми в реализации и действительно защищенными.
В OAuth2 все выглядит немного по другому, тут существуют авторизационные запросы, токены доступа и обновления, и все это требует выполнения трех запросов в самом начале сессии, для того что бы получить необходимые данные. И даже после этого запросы данных вернут ошибку если полученые ранее токены станут просрочеными.
Для того что бы получить новый токен доступа необходимо использовать токен обновления, которые был получен одновременно с предыдущим токеном доступа. Не делает ли это токен доступа бессмысленным с точки зрения безопасности?
Кроме того, как было показано ранее, SSL тоже не всегда безопасен, и поэтому помещение логики получения всех данных через SSL/TLS вместо того что бы использовать HMAC меня несколько смущает.
Про OAuth говорят что он не на 100% защищен, но это завершенный и широко применяемый протокол. Но это не совсем так с точки зрения провайдера.Я вижу и понимаю что происходит в каждом из шести последовательностей в драфте протокола но я не могу собрать все это в одну цельную картину.
Может мне стоит попытатся вникнуть в вопрос более глубоко. Не сочтите это за предвзятое отношение к OAuth2 или невежество. Я просто хочу разобраться.

A:
В прошлом у меня был опыт реализации клиент сервер для OAuth1.0a и 2.0.
Оба протокола OAuth 1.0a и 2.0 поддерживают двухэтапную аутентификацию, когда сервер удостоверяется в валидности идентификатора пользователя и трехэтапную аутентификацию когда сервер удостоверяется в валидности идентификатора пользователя через контент провайдер. Трехэтапная аутентификация подразумевает использование запросов авторизации и токенов доступа, и здесь очень важно отметить что подобная логика присутствует также и в OAuth 1.

Наиболее сложная: трехуэтапная аутентификация

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

  1. Клиент отсылает авторизационный запрос на сервер, который проверяет является ли клиент действительно пользователем системы.
  2. Сервер пересылает клиента на контент провайдер для запроса получения доступа к ресурсам.
  3. Контент провайдер проверяет предоставленные пользователем идентификационные данные и отсылает запросы для получения прав доступа к ресурсам.
  4. Контент провайдер перенаправляет клиента назад на сервер и уведомляет его о успешности или неуспешности выполненой операции. В случае успеха этот запрос содержит авторизационный код.
  5. Сервер делает еще один запрос к контент провайдеру и заменяет авторизационный код на токен доступа.
Сейчас сервер с помощью токена досупа может запрашивать данные у контент провайдера от имени пользователя.
Каждая транзакция (клиент-сервер, сервер-контент провайдер) подвергается валидации  с помощью секрета, но поскольку OAuth 1 может выполнятся с использованием незащищенного соединения, секрет не может передаваться с каждым запросом.
Такая логика, как вы заметили, прсутствует в HMAC. Клиент использует секрет , который известен серверу  для подписывания  аргументов в запросе авторизации. Сервер получает аргументы, подписывает их ключом пользователя, что позволяет проверить достоверность клиента. (в пункте 1 описанном выше).
Эта сигнатура требует от клиента и сервера соблюдать порядок аргументов (таким образом они будут иметь дело с одинаковой строкой) и одна из основных жалоб на Oauth 1это то что протокол требует от сервера и клиента идентичной сортировки и подписи. Это неудобно и даже если все написано правильно есть шанс получить ошибку 401 Unauthorized по непонятной причине. Это увеличивает сложность при написании клиента.
Благодаря тому что Oauth 2.0 требует использование SSL – это избавляет от необходимости сортировки и подписи аргументов. Клиент передает свой секретный код на сервер, где происходит его непосредственная валидация.
Аналогичные требования пристствуют в цепочке сервер – контент провайдер, и поскольку используется SSL – снимаются барьеры по написанию кода доступа к Oauth на сервере.

Таким образом, сервер хранит перманентный токен доступа, который является своеобразным эквивалентом пары логин/пароль. С помощью его можно делать запросы контент провайдеру от имени пользователя с путем  передачи этого самого токена доступа (как аргумента запроса, заголовка HTTP или данных POST формы)
Если сервис контент провайдера доступен через SSL – нет никаких проблем. Если же доступ осуществляется через обычный HTTP, нам следовало бы защитить как-нибудь наш токен доступа. Потому что иначе любой желающий может заполучить этот токен и в любое время использовать его для получения наших персональных данных.
Поэтому в OAuth 2 существует такое понятие как токен обновления (refresh token). Этот токен является эквивалентом перманентного пароля и передается только через защищенный SSL. Когда серверу необходимо получить доступ к контент провайдеру, он с помощью токена обновления запрашивает токен доступа с коротким сроком действия. Таким образом если кто то перехватит наш токен доступа он сможет воспользоваться им ограниченный период времени. Например Google использует пятиминутный интервал в своей реализации OAuth 2 API.
Таким образом за исключением токенов обновления, OAuth 2 упрощает все взиамодействия между клиентом сервером и контент провайдером. А сам токен обновления призван защитить контент в случае если он передается в открытом виде.



Двухэтапная аутентификация

Иногда серверу просто нужно контролировать доступ к своему контенту. Двухэтапная аутентификация позволяет клиенту авторизировать пользователя непосредственно на сервере.
OAuth 2 стандартизирует некоторые расширения OAuth 1 которые нашли широкое распространение. Одним из таких расширений которые мне хорошо известно является Twitter xAuth. Вы можете найти его в OAuth 2 в подразделе "Учетные данные владельца ресурса" (Resources Owner Password Credetials).
В частности, если вы можете доверять клиенту данные учетной записи пользователя (логин и пароль), то клиент может запрашивать токен доступа у контент провайдера непосредственно используя данные учетной записи. Это делает OAuth чрезвычайно удобным для мобильных приложений – в случае с трехэтапной аутентификацией, вам нужно было бы встраивать элемент управления HTTP для того что бы осуществить авторизацию на контент сервере.
В OAuth 1 это не было частью стандарта и требовало подобной процедуры логин как и для всех других запросов.
Я недавно реализовал серверную часть OAuth 2 с учетными данными владельца ресурса и с точки зрения клиента, получение токeна доступа стало проще: запрос токeна доступа с сервера, передача идентификатора клиента и секрета в авторизационном заголовке HTTP и логин пароль пользователя в виде данных формы.



Преимущество: простота

С точки зрения реализции, главным преимуществом OAuth 2 является уменьшенная сложность. Теперь не требуется процедура запроса входа, являющаяся не столько сложной, сколько неудобной. Работы по установлению клиента сервиса стало значительно меньше, что в нашем мобильном мире – очень хорошо. Уменьшенная сложность взаимодейсвтия сервер-контент провайдер делает последнего более масштабируемым.
И плюc ко всему многие расширения OAuth 1 (как например xAuth) были наконец-то стандартизированы.