Как OAuth 2 защищает от таких вещей, как повторные атаки с использованием маркера безопасности?

564

Насколько я понимаю, в OAuth 2 происходит следующая цепочка событий для Site-Aдоступа к информации пользователя из Site-B.

  1. Site-Aрегистрируется Site-Bи получает секрет и удостоверение личности.
  2. Когда Пользователь сообщает Site-Aо доступе Site-B, Пользователь отправляется туда, Site-Bгде ему сообщают, Site-Bчто он действительно хотел бы предоставить Site-Aразрешения для конкретной информации.
  3. Site-Bперенаправляет пользователя обратно Site-Aвместе с кодом авторизации.
  4. Site-Aзатем передает этот код авторизации вместе с его секретом обратно Site-Bв обмен на токен безопасности.
  5. Site-Aзатем делает запросы Site-Bот имени пользователя , связывая токен безопасности с запросами.

Как все это работает с точки зрения безопасности и шифрования на высоком уровне? Как OAuth 2 защищает от таких вещей, как повторные атаки с использованием маркера безопасности?

Уильям Джонс
источник
49
oauth2 просто объяснил здесь: gist.github.com/mziwisky/10079157
Паоло
4
Прочитайте спецификацию: tools.ietf.org/html/rfc6749 Вы можете быть удивлены, насколько это понятно. Это также правильно, что не так уж плохо.
Крис Вандермоттен,
1
Этот вопрос и все его (текущие) ответы сосредоточены на одном конкретном «типе предоставления» в OAuth 2.0 (то есть code), но в OAuth 2.0 определены другие типы предоставления, которые относятся к разным случаям использования (например, не связанным с пользователем).
Ганс З.
4
О, почему бы не заменить «Сайт B» на что-то более читаемое, например «Сайт IdProvider»?
Юрий

Ответы:

1379

Как OAuth 2.0 работает в реальной жизни:

Я ехал по пекарне Олафа по дороге на работу, когда увидел в окне самый вкусный пончик - я имею в виду, что в нем капала шоколадная сладость. Поэтому я вошел внутрь и потребовал «Я должен иметь этот пончик!». Он сказал: «Конечно, это будет 30 долларов».

Да, я знаю, 30 долларов за один пончик! Это должно быть вкусно! Я потянулся к своему кошельку, когда неожиданно услышал, как шеф-повар закричал "НЕТ! Никакого пончика для тебя". Я спросил: почему? Он сказал, что принимает только банковские переводы.

Шутки в сторону? Да, он был серьезен. Я почти ушел, но тут пончик крикнул мне: «Съешь меня, я вкусная ...». Кто я такой, чтобы не подчиняться приказам от пончика? Я сказал хорошо.

Он вручил мне записку со своим именем (шеф-повар, а не пончик): «Скажи им, что Олаф послал тебя». Его имя уже было в записке, так что я не знаю, какой смысл говорить, но хорошо.

Я полтора часа ехал в свой банк. Я передал записку кассиру; Я сказал ей, что Олаф послал меня. Она посмотрела на меня одним из таких взглядов, который говорит: «Я умею читать».

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

В этот момент я голодаю. Я выбежал оттуда, через полтора часа я вернулся, стоя перед Олафом с расширенной запиской. Он взял его, осмотрел и сказал: «Я вернусь».

Я думал, что он получает мой пончик, но через 30 минут я начал подозревать. Поэтому я спросил парня за стойкой «Где Олаф?». Он сказал: «Он пошел, чтобы получить деньги». "Что вы имеете в виду?". «Он принимает к сведению банк».

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

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

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

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

Хорошо, конечно, я бы лучше отдал ему 30 долларов из своего кармана. Но теперь, когда у него была эта записка, я мог просто сказать банку, чтобы он брал по 30 долларов каждую неделю, тогда я мог просто появиться в пекарне, и мне больше не нужно было идти в банк. Я мог бы даже заказать пончик по телефону, если бы захотел.

Конечно, я бы никогда этого не сделал - этот пончик был отвратительным.

Интересно, есть ли у этого подхода более широкие применения? Он упомянул, что это был его второй подход, я мог бы назвать его Olaf 2.0. В любом случае, мне лучше вернуться домой, я должен начать искать новую работу. Но не раньше, чем я получу один из этих клубничных коктейлей из того нового города в другом городе, мне нужно что-нибудь, чтобы смыть вкус этого пончика.

Луис Перес
источник
41
Что ж, на практике Олаф должен иметь возможность снять с вашего счета 30 долларов в любое время, даже если вы не заказываете пончик. Интересно, что это главная цель в реальных сценариях oauth2.0 :) Это, безусловно, отличный ответ, но кто бы ни читает это, пожалуйста, отправляйтесь в Git Gist, который Паоло упомянул в своем комментарии к вопросу ( gist.github.com/mziwisky/ 10079157 ). Хорошее дополнительное чтение, чтобы сделать концепцию кристально ясной.
Самирон
4
Хороший ответ, но 2 пункта для поднятия: 1. Как отметил @Samiron, Олаф сможет взять 30 долларов в любое время, когда захочет. 2. В реальном сценарии OAuth2.0 Олаф не сможет подать пончик до того, как вытащить деньги из банка. Хотя в этом примере он мог оставить чек и просто вручил Луису свой заслуженный пончик. Поэтому, если мы изменим пример, чтобы я разрешил Олафу получить тесто от какой-то третьей стороны, которую я знаю, тогда это имело бы больше смысла, поскольку Олафу пришлось бы получить тесто, прежде чем он начнет печь пончик (при условии, что Олаф - одинокий пончик) был только для демонстрации!).
Ticker23
4
ticker23, история с пончиками, к сожалению, превосходит ваши технические исправления - я был продан за историю, когда я ее прочитал. Это было написано Гомером Симпсоном.
Шеви
4
@Prageeth Olaf всегда несет записку в банк и из банка в защищенном ящике, в котором при утечке чернил протекают чернила, для восстановления банкноты потребуется много жизней. Банк также берет отпечатки пальцев клиентов при первом посещении. Если Олаф потеряет пальцы в результате несчастного случая с выпечкой, ему придется снова попросить Луиса настроить банковский перевод, и в следующий раз банку придется идентифицировать Олафа по татуировке Breaking Bread. ,
Крис
11
Я люблю милые ответы так же, как и следующий человек, и когда их привлекательность помогает сделать ответ более доступным, это потрясающе ... но в конце дня Stack Overflow посвящен обучению людей, и эта милая история не делает этого. Чтобы даже понять аналогию с пончиками, вы уже должны понимать, как работает OAuth2, но весь смысл ответа должен был объяснить именно это. Пожалуйста, рассмотрите возможность редактирования этого (верхнего) ответа, чтобы фактически объяснить концепции, а не просто косвенно ссылаться на них в конце ... даже если это будет стоить шутки или двух.
machineghost
133

Исходя из того, что я прочитал, вот как это все работает:

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

В целом, OAuth 2 на самом деле является очень простой моделью безопасности, и шифрование никогда не вступает в игру. Вместо этого и Секрет, и токен безопасности по сути являются паролями, и все это обеспечивается только безопасностью соединения https.

OAuth 2 не защищен от повторных атак токена безопасности или секрета. Вместо этого он полностью полагается на то, что сайт B отвечает за эти элементы и не позволяет им выйти, а также от их отправки по https во время передачи (https защищает параметры URL).

Целью шага «Код авторизации» является просто удобство, и сам код авторизации не особенно чувствителен. Он предоставляет общий идентификатор токена доступа пользователя X для сайта A, когда запрашивает у сайта B токен доступа пользователя X. Только идентификатор пользователя User X на сайте B не сработал бы, потому что могло быть много выдающихся токенов доступа, ожидающих раздачи на разные сайты одновременно.

Уильям Джонс
источник
28
Вы упустили из виду важную функцию кода авторизации. Почему бы просто не вернуть токен обновления (который вы называете токеном безопасности) немедленно, вместо того, чтобы выполнить дополнительный шаг замены кода авторизации для него? Поскольку захват токена обновления позволил бы повторить атаки, тогда как код авторизации можно использовать только один раз.
Морис Нафталин
3
Хорошо, @mauricen, это имеет смысл .... Но разве атака воспроизведения не может произойти так же хорошо с токеном обновления, так как это то, что заканчивается передачей с каждым запросом?
Мистер Миккель
15
Код авторизации передается через пользователя, поэтому (например) его можно сохранить в виде файла cookie (см. Stackoverflow.com/questions/4065657/… ). Токен обновления проходит непосредственно между двумя сайтами, поэтому он гораздо менее уязвим.
Морис Нафталин
Из любопытства, возвращает ли OAuth какие-либо уникальные идентификаторы для использования программой? Например, я в настоящее время полагаюсь на MAC-адрес для идентификации пользователя, но с учетом сказанного, MAC ненадежны / легко подделываются / и т.д. Я могу просто отказаться от механизма идентификации MAC-адресов и перейти к OAuth, если он позволяет мне однозначно идентифицировать пользователей.
theGreenCabbage
1
Обратите внимание на эту диаграмму: tools.ietf.org/html/rfc6749#section-4.1, что «Секрет» не отображается, только идентификатор клиента (идентификатор в вопросе). Почему Секрет важен и почему он не включен в RFC? Также в этом вопросе есть также локальное состояние, которое рекомендуется передавать при первоначальной передаче идентификатора клиента (A), и перенаправить обратно клиенту вместе с кодом авторизации для защиты от XSSF.
Дэвид Уильямс
104

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

Вот пример использования:

  1. Я захожу в LinkedIn и хочу подключить друзей, которые находятся в моих контактах Gmail. LinkedIn поддерживает это. Он будет запрашивать безопасный ресурс (мой список контактов Gmail) от Gmail. Поэтому я нажимаю эту кнопку:
    Добавить соединение

  2. При открытии учетной записи и пароля появляется веб-страница, на которой отображается страница входа в Gmail:
    Добавить соединение

  3. Затем Gmail показывает страницу согласия, где я нажимаю «Принять»: Добавить соединение

  4. Теперь LinkedIn может получить доступ к моим контактам в Gmail: Добавить соединение

Ниже приведена блок-схема примера выше:

Добавить соединение

Шаг 1. LinkedIn запрашивает токен с сервера авторизации Gmail.

Шаг 2. Сервер авторизации Gmail проверяет подлинность владельца ресурса и показывает пользователю страницу согласия. (пользователь должен войти в Gmail, если он еще не вошел в систему)

Шаг 3. Пользователь разрешает LinkedIn получить доступ к данным Gmail.

Шаг 4: сервер авторизации Gmail отвечает обратно токеном доступа.

Шаг 5. LinkedIn вызывает API Gmail с этим токеном доступа.

Шаг 6. Сервер ресурсов Gmail возвращает ваши контакты, если токен доступа действителен. (Токен будет проверен сервером ресурсов Gmail)

Вы можете получить больше информации об OAuth здесь .

Оуэн Цао
источник
Все ваши изображения пропали без вести. Есть ли шанс, что вы сможете загрузить их в stack.imgur?
ChrisF
1
Как это может быть правильно? Разве этот процесс не инициирован пользователем, сидящим перед браузером, а не LinkedIn. Но у вас есть это как шаг 3. Это то, что я не понимаю.
Мэтт
17
Самое простое объяснение. Спасибо, я никогда не буду покупать пончики снова
OverCoder
4-й шаг linkedin возвращается с токеном авторизации. Это должно быть предоставлено на 5-м шаге, где мы получим токен доступа и токен обновления, который в дальнейшем можно будет использовать для защищенных ресурсов.
17
@amesh Спасибо, вы правы, это поток кода авторизации, здесь я только что изложил в упрощенном виде, чтобы показать основную идею OAuth 2.
Оуэн Цао
24

Рисунок 1, взятый из RFC6750 :

     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+
8bitjunkie
источник
13

Вот как работает Oauth 2.0, хорошо объясненный в этой статье.

введите описание изображения здесь

Сураджа
источник
Можете ли вы описать OAUTH2 с точки зрения не использования Facebook или другой третьей стороны, но если вы используете секретный ключ и токены TOTP с приложением для телефона для защиты веб-приложения?
Аль Грант
В данном примере Facebook является сервером авторизации, который выдает токен доступа любому клиенту, чтобы они могли получить доступ к API-интерфейсам Facebook. Если вы хотите защитить свои API, вам нужно внедрить собственный сервер авторизации. Затем вы решаете, какой тип гранта вы хотите использовать для получения токена доступа. скажи что именно ты хочешь? объясню.
Сурадж
Я смотрю на настройку безопасности Springboot. Клиент (телефон) и веб-приложение обмениваются секретом при регистрации - затем используйте google authenticator для генерации кода времени / секретного кода для ввода при входе в систему в дополнение к паролю.
Аль Грант
мой последний комментарий вас больше просветляет? См. Мой профиль для информации щебета
Al Grant
Вы можете получить идентификатор клиента и секрет при регистрации. Затем телефон делает запрос на вход в систему с идентификатором клиента в вашем веб-приложении (сервере авторизации). веб-приложение проверяет идентификатор клиента и отправляет OTP на телефон. Телефон делает еще один запрос с секретом клиента к веб-приложению для обмена OTP с токеном доступа. телефон использует этот токен доступа для доступа к защищенным ресурсам в веб-приложении. Я думаю, что это будет поток Oauth2 для данного сценария. дайте мне знать, если это поможет вам.
Сурадж
10

Это драгоценный камень:

https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

Очень краткое резюме:

OAuth определяет четыре роли:

  1. Владелец ресурса
  2. клиент
  3. Ресурсный сервер
  4. Сервер авторизации

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

Причина, по которой OAuth существует, заключается в том, что GMail небезопасно хранить ваше имя пользователя и пароль Yahoo.

введите описание изображения здесь

Belfield
источник
8

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

Для уточнения и, в частности, для решения вопроса OP «Как OAuth 2 защищает от таких вещей, как атаки воспроизведения с использованием маркера безопасности?», В официальных рекомендациях по реализации OAuth 2 предусмотрены две дополнительные защиты :

1) Жетоны обычно имеют короткий срок действия ( http://tools.ietf.org/html/rfc6819#section-5.1.5.3 ):

Короткий срок действия токенов является средством защиты от следующих угроз:

  • переигрывать ...

2) Когда токен используется сайтом A, рекомендуется, чтобы он был представлен не как параметры URL, а в поле заголовка запроса авторизации ( http://tools.ietf.org/html/rfc6750 ):

Клиенты ДОЛЖНЫ делать аутентифицированные запросы с токеном-носителем, используя поле заголовка запроса «Авторизация» со схемой HTTP-авторизации «Носитель». ...

Метод application / x-www-form-urlencoded НЕ ДОЛЖЕН использоваться, за исключением случаев, когда участвующие браузеры не имеют доступа к полю заголовка запроса «Авторизация». ...

URI Query Parameter ... включен для документирования текущего использования; его использование не рекомендуется из-за недостатков безопасности

Будет
источник
3

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

сходство

Все потоки грантовых типов имеют 2 части:

  • Получить токен доступа
  • Использовать токен доступа

Вторая часть «Использовать токен доступа» одинакова для всех потоков.

разница

Первая часть потока «получить токен доступа» для каждого типа предоставления варьируется.

Тем не менее, в целом часть «получить токен доступа» может быть обобщена как состоящая из 5 шагов:

  1. Предварительно зарегистрируйте свое приложение (клиент) у поставщика OAuth, например, в Twitter и т. Д., Чтобы получить идентификатор клиента / секрет
  2. Создайте кнопку входа в социальную сеть с идентификатором клиента и необходимыми областями / разрешениями на своей странице, чтобы при нажатии пользователь перенаправлялся к провайдеру OAuth для аутентификации
  3. OAuth провайдер запрашивает у пользователя разрешение на ваше приложение (клиент)
  4. OAuth-провайдер выдает код
  5. Приложение (клиент) получает токен доступа

Ниже приведена диаграмма, показывающая, как каждый поток типов грантов отличается на основе 5 шагов.

Эта диаграмма из https://blog.oauth.io/introduction-oauth2-flow-diagrams/

введите описание изображения здесь

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

Учетные данные клиента : если ваше приложение обслуживает только одного пользователя

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

Код авторизации : лучший способ получить авторизацию пользователя

Неявный : если ваше приложение мобильное или одностраничное

Более подробное объяснение выбора здесь: https://blog.oauth.io/choose-oauth2-flow-grant-types-for-app/

nethsix
источник