Какова цель типа неявного разрешения авторизации в OAuth 2?

254

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

Оба потока начинаются одинаково (источник: http://tools.ietf.org/html/draft-ietf-oauth-v2-22 ):

  1. Клиент инициирует поток, направляя пользовательский агент владельца ресурса в конечную точку авторизации.
  2. Сервер авторизации аутентифицирует владельца ресурса (через агента пользователя) и устанавливает, предоставляет ли владелец ресурса запрос клиента на доступ или отклоняет его.
  3. Предполагая, что владелец ресурса предоставляет доступ, сервер авторизации перенаправляет агента пользователя обратно клиенту, используя ранее предоставленный URI перенаправления (в запросе или во время регистрации клиента).
    • URI перенаправления включает в себя код авторизации (поток кода авторизации)
    • URI перенаправления включает маркер доступа во фрагмент URI (неявный поток)

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

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

Отсюда мой вопрос: что здесь получилось, если пропустить шаг аутентификации клиента?

Дэн Тафлин
источник
Посмотрите на это: ibm.com/developerworks/wikis/display/…
Håvard Geithus
5
Ссылка в предыдущем комментарии мертва. Вот обновленный
AndrewR
3
Я прочитал все ответы здесь, но я все еще не понимаю, как не требуется секрет секретного клиента для получения токена доступа. Допустим, TrustedAppDeveloper выпускает TrustedPopularApp, который позволяет пользователям давать ему разрешения (например, с помощью Twitter oauth) с использованием неявного предоставления. Если я EvilAppDeveloper, что мешает мне создать приложение, которое передает TrustedPopularAppId в качестве client_id в неявном запросе на предоставление, а затем выполнять действия (например, рассылку спама) от имени пользователя, которые теперь выглядят так, как будто они исходят от TrustedPopularApp ?
adevine
Я удивляюсь тому же, что и Адевин. Но, скорее всего, приложения, которые требуют неявного запроса на предоставление, не нуждаются в дополнительной аутентификации, поскольку все они получают?
Сделано
13
@adevine Что может помешать EvilApp в вашем сценарии пройти аутентификацию в Twitter как TrustedPopularApp, так это то, что он не может получать обратные вызовы из Twitter, они всегда будут отправляться на URI, который был определен при регистрации идентификатора клиента
Ivan

Ответы:

196

Вот мои мысли:

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

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

Таким образом, ответ на вопрос "что было получено?" это "простота".

Филипп Пешин
источник
4
Спасибо. Хорошо, что в потоке кода авторизации владельцу ресурса никогда не нужно видеть токен доступа, тогда как в клиентах javascript это неизбежно. Однако клиентский секрет все еще можно было сохранить от клиентов javascript, используя поток кода авторизации: после аутентификации и получения токена доступа код на стороне сервера затем передал бы токен клиенту javascript. Однако теперь я вижу, что неявный поток грантов позволяет распространять javascript oauth SDK, такие как Facebook, освобождая разработчиков от необходимости полностью писать свой собственный oauth-код.
Дэн Тафлин
3
Я мог бы добавить, что поток кода авторизации позволяет клиентам хранить токены и использовать их повторно. В неявном потоке у вас не всегда есть эта опция, и поэтому неявный поток - это прагматичный выбор между уровнем безопасности и удобством.
PålOliver
2
На это отвечает только половина, а «что было потеряно»?
EralpB
3
Я не думаю, что это исчерпывающий ответ, неявный поток предназначен не для того, чтобы получить преимущество от простоты, а для компрометации проблем безопасности с клиентским приложением. Auth codeвместе с client_idи client_secretиспользуются для идентификации доверенных клиентов, которые могут обновлять токены для длительного входа в систему и для «автономного входа» . Однако в клиентском приложении нет способа зарегистрировать каждого клиента, поэтому «упрощенный» тип неявного предоставления для временного доступа к пользовательской информации
Чэнь Се,
1
Включение секрета клиента не только делает процесс более сложным, но и делает его менее безопасным . Секрет клиента не является секретом, если его необходимо перечислить в коде на стороне клиента, и поэтому он будет открыт для Интернета. Если ваш идентификатор клиента используется только в неявных потоках, это не проблема. Но если он также используется где-то в вашей платформе для обновления токенов или предоставления кода авторизации, то раскрытие соответствующего секрета является большой проблемой.
Атараксия
94

Это там по соображениям безопасности, а не для простоты.

Вы должны учитывать разницу между пользовательским агентом и клиентом :

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

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

В случае разрозненного пользовательского агента и клиента имеет смысл предоставить код авторизации . Например, пользователь использует веб-браузер (user-agent) для входа в свою учетную запись Facebook на Kickstarter. В этом случае клиент является одним из серверов Kickstarter, который обрабатывает логины пользователей. Этот сервер получает токен доступа и токен обновления от Facebook. Таким образом, этот тип клиента считается «безопасным», из-за ограниченного доступа токены могут быть сохранены, и Kickstarter может получить доступ к ресурсам пользователей и даже обновить токены доступа без взаимодействия с пользователем.

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

artkoenig
источник
2
Я вижу, что мой браузер вошел в мою учетную запись Google в течение нескольких месяцев. Так Google использует токен доступа в браузере или токен с длительным сроком действия? какая разница в использовании между токеном доступа с большим сроком действия и токеном доступа? любой другой клиент может перехватить токен доступа и использовать его, когда отсутствует владелец ресурса.
Мохаммед Никраван
Я полагаю, вы имеете в виду разницу между токеном обновления и токеном с длительным сроком действия ? Токен обновления не следует сохранять в небезопасных сценариях, однако вы можете сохранить свой токен доступа (например, в локальном хранилище браузера). Безопасность достигается за счет минимального срока службы вашего токена доступа, хотя он по-прежнему удобен для ваших пользователей (например, вы можете выйти из системы автоматически после x минут бездействия). Если вы используете маркеры доступа с длительным сроком службы, вы фактически делаете токены обновления устаревшими.
artkoenig
Спасибо за ваше объяснение, но у меня есть еще одна путаница. Я не понимаю, зачем нам поток «Код авторизации». Мы можем достичь того же результата на сервере неявным потоком (access_token) и токеном обновления. Похоже, единственное соображение безопасности неявного потока заключается в том, что код доступа должен иметь короткий срок службы, поэтому его нельзя использовать на сервере. Хорошо, но токен обновления решает эту проблему. Почему мы должны использовать поток auth_code и запрашивать access_token по этому токену на сервере для получения access_code, тогда как мы можем достичь того же результата с refresh_token?
Мохаммед Никраван
"токен может быть легко извлечен другими приложениями" Как?
17
@MohammadNikravan ищите ответ в stackoverflow.com/q/13387698/355438
Lu55
60

Обычное объяснение состоит в том, что неявное предоставление легче реализовать, когда вы используете клиент JavaScript. Но я думаю, что это неправильный взгляд на это. Если вы используете клиент JavaScript, который запрашивает защищенные ресурсы напрямую через XMLHttpRequest, неявное предоставление является единственным вариантом, хотя и менее безопасным. *

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

Но - и это момент, который легко упустить - безопасность потока кода авторизации работает, только если веб-сервер защищен сеансом, который устанавливается с помощью аутентификации пользователя (входа в систему). Без сеанса недоверенный пользователь может просто отправлять запросы на веб-сервер, используя client_id, и он будет таким же, как если бы у пользователя был токен доступа. Добавление сеанса означает, что только аутентифицированный пользователь может получить доступ к защищенным ресурсам. Client_id - это просто «идентификатор» веб-приложения JS, а не аутентификация указанного веб-приложения.

Это также означает, что вы можете завершить сеанс до истечения срока действия токена OAuth. Не существует стандартного способа аннулировать токен доступа. Но если ваш сеанс истекает, маркер доступа бесполезен, так как никто не знает его, кроме веб-сервера. Если недоверенный пользователь получит доступ к вашему ключу сеанса, он сможет получить доступ к защищенным ресурсам только в течение срока действия сеанса.

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

* РЕДАКТИРОВАТЬ: В последнее время люди рекомендуют избегать использования неявного гранта, даже в веб-приложениях без сервера. Вместо этого вы можете использовать предоставление кода авторизации с пустым секретом вместе с PKCE. Предоставление кода авторизации позволяет избежать сохранения токена доступа в истории браузера, а PKCE не раскрывает его, если кто-то перехватывает URL-адрес перенаправления для кражи кода авторизации. В этом случае вам понадобится сервер, чтобы избежать возврата токена обновления, поскольку ваш клиент, вероятно, не сможет безопасно его сохранить. И он должен выдать токен доступа с теми же ограничениями, которые указаны выше.

JW.
источник
21

Это сводится к следующему: если пользователь запускает веб-приложение на основе браузера или «общедоступное» (JavaScript) без серверного компонента, то пользователь неявно доверяет приложению (и браузеру, в котором оно выполняется, потенциально с другим браузером). приложения ...).

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

Однако последствия для безопасности являются значительными. С http://tools.ietf.org/html/rfc6749#section-10.3 :

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

С http://tools.ietf.org/html/rfc6749#section-10.16 :

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

Будет
источник
Что вы подразумеваете под «общедоступным» (JavaScript) веб-приложением без серверного компонента? Как может быть веб-приложение без сервера?
Замми Пейдж
2
@ZammyPage, это то, что часто называют одностраничным приложением (SPA). Все приложение обслуживается из статического ресурса. Затем Javascript в приложении динамически получает доступ к любым ресурсам, которые ему нужны, на любых ресурсных серверах, к которым он может получить доступ. Не существует сервера, который генерирует содержимое клиента: javascript в клиенте изменяет DOM по мере необходимости для представления ресурсов, к которым он получил доступ.
Элрой Флинн
13

Я не уверен, что правильно понимаю ответ и комментарий Дэна. Мне кажется, что в ответе указаны правильные факты, но он точно указывает на то, что спросил ОП. Если я правильно понимаю, главное преимущество неявного потока предоставления прав состоит в том, что клиент, такой как приложение JS (например, расширение Chrome), не должен раскрывать секрет клиента.

Дэн Тафлин сказал:

... в коде авторизации владельцу ресурса никогда не нужно видеть токен доступа, тогда как в клиентах javascript это неизбежно. Однако клиентский секрет все еще может храниться в клиентах javascript с использованием потока кода авторизации.

Возможно, я вас неправильно понял, но клиент (в данном случае приложение JS) должен передать учетные данные клиента (ключ клиента и секрет) серверу ресурсов в потоке кода авторизации, верно? Секрет клиента не может быть «скрыт от JS».

tzuchien.chiu
источник
6
Я понимаю, что это старый вопрос, но это лучший ответ, чем принятый. Причина неявного предоставления заключается в том, что клиент javascript не может хранить секрет и поэтому не может быть аутентифицирован. Таким образом, для обеспечения безопасности сервер авторизации должен полагаться исключительно на регистрацию URI перенаправления и пользовательский агент. Вы передаете токены авторизации только пользовательскому агенту и только в определенном URI перенаправления, теоретически предотвращая перехват (поскольку злонамеренный пользователь, которому не принадлежит домен URI перенаправления, не может выполнить код в пользовательском агенте в этом URI).
gregates
Действительно принятый ответ смутил меня. Заставил меня думать, что я неправильно понял, что такое client_secret! Этот ответ и вышеприведенный комментарий на месте.
Sarsaparilla
9

Хотя Implicit Grant был разработан для поддержки приложений, которые не могут защитить секрет клиента, включая клиентские приложения JavaScript, некоторые провайдеры реализуют альтернативу, используя вместо этого код авторизации без Client Secret. OAuth 2.0 IETF RFC-6749 был опубликован в 2012 году, а текущие рекомендации - некоторые недавние обсуждения относятся к 2017 году.

Обсуждение 2017 года по списку рассылки IETF OAuth доступно от следующих разработчиков:

Узнайте больше здесь:

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

...

Ранее было рекомендовано, чтобы браузерные приложения использовали поток «Неявный», который немедленно возвращает токен доступа и не имеет шага обмена токенами. За время, прошедшее с тех пор, как спецификация была изначально написана, передовая отраслевая практика изменилась, чтобы рекомендовать использовать поток кода авторизации без секрета клиента. Это предоставляет больше возможностей для создания безопасного потока, например, с помощью параметра состояния. Рекомендации: Redhat , Deutsche Telekom , Smart Health IT .

Переход к Auth Code без Client Secret из Implicit Grant также упоминается для мобильных приложений здесь:

Grokify
источник
Я думаю, что вы хотите быть осторожным с этой рекомендацией. Это было рекомендовано в руководстве для нативных приложений, а не спа. К сожалению, нет хорошего руководства по SPA, как задокументировано во многих онлайн-дискуссиях, форумах и даже в списке рассылки oauth-wg.
Том
Рекомендация переходить на код авторизации без секрета от неявного предоставления является рекомендацией как для SPA, так и для мобильных приложений, но мой отрывок выше относится только к SPA. В указанной статье используется аналогичный текст как для SPA, так и для мобильных приложений, но с языком «приложения для браузера», «мобильные и нативные приложения» в соответствующем тексте. Также ссылки на Redhat, DT, Smart Health IT специфичны для SPA и не включены в примечание для мобильных приложений. Я добавил в ответ глубокую ссылку на SPA, чтобы их было легче найти. Пожалуйста, разместите несколько ссылок на обсуждения, которые вы упоминаете.
Grokify
Довольно недавнее (2018 г.) обсуждение oauth-wg можно найти здесь ietf.org/mail-archive/web/oauth/current/msg18020.html . RFC 8252 предназначен для нативных приложений, поскольку в заголовке предлагается «OAuth 2.0 для нативных приложений». Ссылки на Redhat, DT, Smart Health IT - это ответы на обсуждение списка рассылки, а не RFC, рабочий проект и т. Д.
Tom
3

в дополнение к другим ответам также важно понимать, что неявный профиль допускает поток только по переднему каналу в отличие от потока кода авторизации, который требует обратного вызова к серверу авторизации; это становится очевидным в OpenID Connect, который является протоколом единого входа, построенным поверх Auth 2.0, где неявный поток напоминает довольно популярную привязку SAML POST, а поток кода авторизации напоминает менее широко развернутую привязку артефакта SAML

Ханс З.
источник
3

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

В потоке аутентификации коррупция не может, потому что она не знает секрет клиента.

аллюр
источник
2

https://tools.ietf.org/html/rfc6749#page-8

неявный

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

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

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

Рзв Разван
источник
1

Я думаю, Уилл Кейн ответил на это, когда сказал: «Учетные данные клиента не приносят пользы по той же причине. (Любой клиент может попытаться использовать этот поток.)» Также учтите, что redirect_uri для неявного потока может быть «localhost» - обратного вызова нет. производится с сервера авторизации для неявного потока. Поскольку нет никакого способа предварительно доверить клиенту, пользователь должен был бы одобрить выпуск пользовательских утверждений.

Майк Шварц
источник
1

Неявное предоставление позволяет получать токены из конечной точки авторизации с помощью GET. Это означает, что сервер авторизации не должен поддерживать CORS.

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

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

  • возможность доставки и использования токенов по обратному каналу для конфиденциальных клиентов
  • не выставлять токены в истории браузера для публичных клиентов
  • прерывание несанкционированного потока перед выдачей токенов - с PKCE , для «всех типов клиентов OAuth»
ко ла
источник
0

Я только что столкнулся с какой-то статьей об OAuth 2.0. Автор утверждает, что причина неявного потока в том, что приложения JS были очень ограничены в своих запросах:

если вам интересно, почему неявный тип был включен в OAuth 2.0, объяснение простое: та же политика происхождения. Тогда внешним приложениям не разрешалось отправлять запросы различным хостам для получения токена доступа с использованием кода. Сегодня у нас есть CORS (Cross-Origin Resource Sharing).

https://medium.com/securing/what-is-going-on-with-oauth-2-0-and-why-you-should-not-use-it-for-authentication-5f47597b2611

Lu55
источник