В чем разница между кодом авторизации OAuth и неявными рабочими процессами? Когда использовать каждый?

165

OAuth 2.0 имеет несколько рабочих процессов. У меня есть несколько вопросов относительно двух.

  1. Поток кода авторизации - пользователь входит в систему из клиентского приложения, сервер авторизации возвращает код авторизации в приложение. Затем приложение обменивает код авторизации на токен доступа.
  2. Поток неявного предоставления - пользователь входит в систему из клиентского приложения, сервер авторизации выдает токен доступа клиентскому приложению напрямую.

В чем разница между двумя подходами с точки зрения безопасности? Какой из них более безопасный и почему?

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

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

divyanshm
источник

Ответы:

204

Это access_tokenто, что вам нужно называть защищенным ресурсом (API). В потоке кода авторизации есть 2 шага для его получения:

  1. Пользователь должен аутентифицироваться и возвращает codeAPI потребителю (так называемый «Клиент»).
  2. «Клиент» API (обычно ваш веб-сервер) обменивается codeполученным в # 1 на access_tokenаутентификацию с помощьюclient_id иclient_secret
  3. Затем он может вызвать API с access_token.

Итак, есть двойная проверка: пользователь, которому принадлежат ресурсы, обнаруженные через API, и клиент, использующий API (например, веб-приложение). Оба подтверждены для доступа, который будет предоставлен. Обратите внимание на «авторизацию» природы OAuth здесь: пользователь предоставляет доступ к своему ресурсу (через codeвозвращенный после аутентификации) приложению, приложение получаетaccess_token и вызывает от имени пользователя.

В неявном потоке шаг 2 опущен. Таким образом, после аутентификации пользователя, access_tokenвозвращается непосредственно, что вы можете использовать для доступа к ресурсу. API не знает, кто вызывает этот API. Кто-нибудь сaccess_token возможность, в то время как в предыдущем примере это было бы только веб-приложение (его внутренние компоненты обычно никому не доступны).

Неявный поток обычно используется в сценариях, где хранение client idи client secretне рекомендуется (например, устройство, хотя многие все равно делают это). Вот что означает отказ от ответственности. Люди имеют доступ к клиентскому коду и поэтому могут получить учетные данные и притвориться, что стали клиентами ресурсов. В неявном потоке все данные изменчивы, и в приложении ничего не хранится.

Эухенио Пейс
источник
Спасибо за ваше объяснение, но я не понимаю, зачем нам нужен еще один поток кода авторизации. Мы можем достичь того же результата на сервере неявным потоком (access_token) и токеном обновления. Похоже, единственное соображение безопасности неявного потока заключается в том, что код доступа должен иметь короткий срок службы, поэтому его нельзя использовать на сервере. Хорошо, но токен обновления решает эту проблему. Почему мы должны использовать поток auth_code и запрашивать у него access_token для получения access_code?
Мохаммед Никраван
Ну ... так работает протокол. Возможно, вы захотите прочитать анализ спецификаций угроз для более подробного ознакомления с достоинствами безопасности одного и другого.
Эудженио Пейс
Я знаю, что первоначальному ответу уже более 5 лет, но это самое простое и чистое объяснение, которое я когда-либо читал. Спасибо @EugenioPace
Таха Ахмад
1
@ Madnik7G Причина ортогональна тому, что объясняет этот ответ (прекрасно): может быть вовлечена третья сторона. Весь поток организован пользовательским агентом (например, браузером), но в конце сервер авторизации (например: «Войти через Facebook») будет напрямую общаться с клиентом (скажем, с BFF на стороне сервера), который будет в конечном итоге получить доступ к ресурсу, так что пользовательский агент никогда не будет иметь прямого доступа.
Даниэль Лэнгдон,
Спасибо! Да, происходит 3 связи: браузер и AS 9e.g. Facebook). Это /authorizeпросьба. Браузер и веб-сайт пытаются вызвать API (он же клиент). Это redirect_uri+, codeвозвращаемый AS после успешной аутентификации. Наконец, клиент вызова AS за кулисами, обмениваясь codeдля access_token. Это token endpointв литературе. В общем, AS никогда никому не звонит. Это всегда отвечает.
Эухенио Пейс
52

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

  • Код авторизации-потока позволяет конечному токену доступа никогда не достигать и никогда не сохраняться на машине с браузером / приложением . Временный код авторизации предоставляется машине с браузером / приложением, которая затем отправляется на сервер. Затем сервер может обмениваться им с токеном полного доступа и иметь доступ к API и т. Д. Пользователь с браузером получает доступ к API только через сервер с токеном.
  • Неявный поток может включать только две стороны, и окончательный токен доступа сохраняется на клиенте вместе с браузером / приложением. Если этот браузер / приложение скомпрометировано, значит, их токен может быть опасным.

Т.Л., д - р не использовать неявный поток , если вы не доверяете машине пользователей , чтобы держать лексемы , но вы делаете доверять свои собственные серверам.

Джордж Пауэлл
источник
12
Re: Пользователь с браузером получает доступ к API только через сервер с токеном. Но серверу необходимо что-то отправить в браузер, чтобы входящие запросы можно было связать с токеном, который хранится на стороне сервера. Печенье, если хотите. Если сервер не передает токен JS, работающему в браузере, он должен передать что-то еще, что клиент (браузер) должен передать серверу, чтобы позволить серверу действовать от имени конкретного клиента.
Cheeso
Да, печенье. Таким образом, вы должны настроить свой сервер и клиент браузера для защиты от подделки межсайтовых запросов.
Марсель
@Marcel Я хотел бы знать, что как только мы получим код, как и где происходит обмен, чтобы получить фактический access_tokenс помощью authorization code.
Чираг Сони
14

Разница между ними заключается в том, что:

  1. В неявном потоке токен возвращается напрямую через URL-адрес перенаправления со знаком «#», который используется в основном в клиентах javascript или мобильных приложениях, у которых нет серверной стороны, и клиенту не нужно предоставлять свой секрет в некоторых реализациях. ,

  2. В потоке кода авторизации код возвращается с "?" чтобы быть читаемым на стороне сервера, серверная сторона должна предоставить клиенту секрет на этот раз для URL токена, чтобы получить токен как объект json с сервера авторизации. Он используется в том случае, если у вас есть сервер приложений, который может обрабатывать это и хранить маркер пользователя с его / ее профилем в своей собственной системе, и в основном используется для обычных мобильных приложений.

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

Bassem Reda Zohdy
источник
Код авторизации хранится на сервере в течение 10 минут для фейсбука. Это было выпущено в их декабре 5,2012 изменения. Мой вопрос, в основном, заключается в том, в чем разница между двумя с точки зрения безопасности / производительности. Я знаю, что делают оба потока - но в чем преимущество использования кода авторизации - добавление еще одного шага к рабочему процессу.
Дивьяншм
он не отправляет токен пользовательскому приложению, так как прямое соединение между клиентским приложением и сервером авторизации скрыто от пользователя, и, как я уже говорил, это может быть очень защищенный канал, не такой как канал от пользователя к клиентскому приложению.
Bassem Reda Zohdy
Производительность в коде авторизации приводит к тому, что вы дважды попадаете на сервер аутентификации, поэтому это занимает больше времени, также клиентский сервер будет хранить маркер пользователя, что также добавит больше времени.
Bassem Reda Zohdy
2
Ох, хорошо! Я мог не заметить этого. Таким образом, в основном поток кода авторизации должен использоваться системами, где весь сервер является клиентом - браузер делает запрос и получает код. код отправляется на клиентский сервер, который безопасно подключается к серверу ресурсов. Я правильно понимаю? Маркер доступа никогда не достигает компьютера конечного пользователя?
Дивьяншм
1
Маркер доступа никогда не достигает компьютера конечного пользователя? да, он связан с вашим профилем с сервером клиентских приложений.
Bassem Reda Zohdy
4

Неявное предоставление похоже на предоставление кода авторизации с двумя отличиями.

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

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

Подробности вы найдете здесь http://oauth2.thephpleague.com/authorization-server/which-grant/

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

Неявный поток

преимущества

  • Проще всего реализовать

Недостатки

  • Доступ к токенам, видимым в браузере
  • Происхождение маркеров доступа не может быть определено
  • Срок действия маркеров доступа не может истечь (согласно политике Google)

Поток кода авторизации

преимущества

  • Самый безопасный
  • Жетоны доступа и токены обновления могут быть созданы, только если известен общий секрет
  • Может быть улучшен с новыми функциями безопасности и UX, когда они станут доступны

Недостатки

  • Необходимо реализовать несколько конечных точек аутентификации

Цитирование: https://developers.google.com/actions/develop/identity/oauth2-overview#supported_oauth_20_flows

vlazzle
источник
2

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

Поток кода авторизации !!!

  • Если у вас есть сервер веб-приложений, который действует как клиент OAuth
  • Если вы хотите иметь долгоживущий доступ
  • Если вы хотите иметь автономный доступ к данным
  • когда вы отвечаете за вызовы API, которые делает ваше приложение
  • Если вы не хотите пропускать свой токен OAuth
  • Если вы не хотите, чтобы ваше приложение запускалось через поток авторизации каждый раз, когда ему требуется доступ к данным. ПРИМЕЧАНИЕ. Поток неявного предоставления не поддерживает токен обновления, поэтому, если сервер авторизации регулярно истекает токены доступа, ваше приложение должно будет запускаться через поток авторизации всякий раз, когда ему требуется доступ.

Неявный поток грантов !!!

  • Если у вас нет сервера веб-приложений для работы в качестве клиента OAuth
  • Если вам не нужен долгоживущий доступ, т.е. требуется только временный доступ к данным.
  • Если вы доверяете браузеру, в котором запускается ваше приложение, и существует ограниченная обеспокоенность тем, что маркер доступа может проникнуть ненадежным пользователям.
Аман Туладхар
источник
2

Какой из них более безопасный и почему?

Они оба безопасны, это зависит от среды, в которой вы их используете.

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

Это просто. Ваш клиент не защищен. Давайте посмотрим на это подробнее.

Предположим, что вы разрабатываете приложение против Instagram API, поэтому вы регистрируете приложение Instagramи определяете, какое API'sвам нужно. Instagramпредоставит вам client_idиclient_secrect

На вашем веб-сайте вы создали ссылку, которая говорит. «Приходите и используйте мое приложение». При нажатии на это ваше веб-приложение должно сделать два звонка Instagram API.

Firstотправить запрос Instagram Authentication Serverс указанными ниже параметрами.

1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token. 

Вы не отправляетеclient_secret , Вы не можете доверять клиенту (Пользователь и / или его браузер, которые пытаются использовать ваше приложение). Клиент может увидеть url или java скрипт и client_secrectлегко найти его . Вот почему вам нужен еще один шаг.

Вы получаете codeи state. codeЗдесь temporaryи не сохраняется где - либо.

Затем вы secondзвоните Instagram API(с вашего сервера)

 1. `grant_type` with the value of `authorization_code`
 2. `client_id` with the client identifier
 3. `client_secret` with the client secret
 4. `redirect_uri` with the same redirect URI the user was redirect back to
 5. `code` which we have already received.

Поскольку вызов сделан с нашего сервера, мы можем безопасно использовать client_secret(что показывает, как мы), codeчто показывает, что пользователь выдал client_idправо использовать ресурс.

В ответ мы будем иметь access_token

Алиреза Фаттахи
источник
1

С практической точки зрения (что я понял), основная причина наличия потока кода Authz:

  1. Поддержка токенов обновления (долгосрочный доступ к приложениям от имени Пользователя), не поддерживается неявно: см. Https://tools.ietf.org/html/rfc6749#section-4.2
  2. Поддержка страницы согласия, на которой владелец ресурса может контролировать, какой доступ предоставить (вид страницы разрешений / авторизации, которую вы видите в Google). То же самое не существует в неявном виде. Смотрите раздел: https://tools.ietf.org/html/rfc6749#section-4.1 , точка (B).

«Сервер авторизации аутентифицирует владельца ресурса (через агента пользователя) и устанавливает, разрешает ли владелец ресурса запрос клиента на доступ»

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

dvsakgec
источник
0

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

Краткая история : Тип предоставления кода авторизации хранит конфиденциальную информацию из истории браузера, а передача токена зависит только от защиты HTTPS сервера авторизации.

Более длинная версия:

Далее я буду придерживаться терминологии OAuth 2, определенной в RFC (это краткое чтение): сервер ресурсов , клиент , сервер авторизации , владелец ресурса .

Представьте, что вы хотите, чтобы какое-то стороннее приложение (= клиент) получило доступ к определенным данным вашей учетной записи Google (= сервер ресурсов). Давайте просто предположим, что Google использует OAuth 2. Вы являетесь владельцем ресурса для учетной записи Google, но сейчас вы используете стороннее приложение.

Сначала клиент открывает браузер, чтобы отправить вас по защищенному URL-адресу сервера авторизации Google. Затем вы одобряете запрос на доступ, и сервер авторизации отправляет вас обратно на ранее заданный клиентом URL-адрес перенаправления с кодом авторизации в строке запроса. Теперь о двух ключевых моментах:

  1. URL этого перенаправления попадает в историю браузера . Таким образом, мы не хотим, чтобы здесь существовал долгосрочный токен прямого использования. Краткосрочный код авторизации менее опасен в истории. Обратите внимание, что тип неявного предоставления действительно помещает токен в историю.
  2. Безопасность этого перенаправления зависит от сертификата HTTPS клиента , а не от сертификата Google. Таким образом, мы получаем безопасность передачи клиента как дополнительный вектор атаки (для того, чтобы это было неизбежно, клиент должен быть не-JavaScript. Поскольку в противном случае мы могли бы передавать код авторизации через URL фрагмента, где код не проходил бы по сети. Это может быть причиной, по которой Implicit Grant Type, который делает использовать фрагмент URL, используемый для быть рекомендован для клиентов JavaScript, несмотря на то, что это больше не так.)

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

Карстен Фюрманн
источник