OAuth2 ROPC против базовой аутентификации для публичных API REST?


21

Особый случай использования, который меня интересует, - это аутентификация клиентов REST по общедоступным конечным точкам сервера (например, общедоступный API REST).

Самым простым решением здесь является Basic Auth . Но я часто слышу, что OAuth2 рекламируется как превосходное решение для аутентификации практически во всех обстоятельствах.

Дело в том, что единственным типом предоставления OAuth2, который возможен для аутентификации клиента REST на сервере REST, являются учетные данные владельца ресурса (ROPC) , поскольку для предоставления кода и неявного предоставления требуется пользовательский интерфейс / веб-страница (размещенная на сервере проверки подлинности ) для Пользователь, чтобы войти и вручную авторизовать клиентское приложение.

ROPC работает, отправляя имя пользователя / пароль владельца ресурса и идентификатор клиента в качестве параметров строки запроса ?!? Это даже менее безопасно (IMHO), чем Basic Auth, который, по крайней мере, base-64 кодирует учетные данные и отправляет их в заголовок, который может быть зашифрован TLS!

Поэтому я спрашиваю: действительно ли OAuth2 ROPC в контексте общедоступных API REST лучше, чем Basic Auth? Что безопаснее, чем OAuth2 ROPC?


Обновить

Я только что прочитал эту прекрасную статью, в которой объясняется безопасность REST от Amazon, не основанная на OAuth2, для AWS. По сути, это решение на основе закрытого ключа, в котором хэши каждого запроса REST генерируются и отправляются в качестве вспомогательных элементов наряду с обычным (незашифрованным) запросом. Только клиент и сервер знают закрытый ключ, поэтому, когда сервер получает запрос (опять же, содержащий обычный запрос + хешированный запрос), сервер ищет закрытый ключ клиента, применяет тот же хэш к обычному запросу, и затем сравнивает два хэша.

Это звучит намного сложнее, сложнее и безопаснее, чем ROPC OAuth2! Пока я не пропущу что-то важное здесь, OAuth2 ROPC просто отправляет client_id, usernameи passwordкак параметры строки запроса ... совершенно и совершенно небезопасно! Это решение, основанное на HMAC / хешировании, кажется гораздо более впечатляющим и безопасным.

Дело в том, что даже автор этой статьи продолжает:

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

Ба-ба-bwhat?!?! Если OAuth2 менее безопасен, чем это умное решение на основе HMAC / хеша, почему автор этой статьи считает, что OAuth нужно принять в какой-то момент. Я весьма озадачен.


О каком клиенте вы говорите? Я предполагаю, что у большинства клиентов будет пользовательский интерфейс. В этом случае вы можете загрузить страницу входа в OAuth в веб-представлении (для настольного компьютера, мобильного устройства) или перенаправить на него напрямую (через Интернет). Я не понимаю, почему вы должны избегать пользовательского интерфейса.
дециклон

@decyclone, пожалуйста, прочитайте самое первое предложение к вопросу! Я рассказываю об аутентификации клиентов REST (безголовый HTTP) с помощью сервисов REST.
Смеб

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

@decyclone no Чистый клиент REST не имеет никакого пользовательского интерфейса, хотя пользовательские интерфейсы обычно используют чистый клиент REST для подключения к службе REST. Одним из вариантов использования является инструмент командной строки, который использует клиент REST для отправки пользовательских команд (введенных в оболочке) в службу REST. Получение пользовательского интерфейса из оболочки просто не является приемлемым решением.
Смеб

1
Но, я должен отметить, есть много других вариантов использования вне командной строки / оболочки. Другим примером использования является клиент REST / HTTP на языке Java / Ruby / Python, который не имеет пользовательского интерфейса и может работать на внутреннем сервере без пользовательского интерфейса. Внутренний сервер должен взаимодействовать с другим внутренним сервером через REST. Здесь не только было бы неудобно и хакерски вставлять пользовательский интерфейс, когда бэкэнд-серверу № 1 необходимо общаться с бэкэнд-сервером № 2, реальная проблема в том, что нет браузера / клиента пользовательского интерфейса, чтобы отобразить страницу входа, и нет человека. быть там, чтобы войти!
Смеб

Ответы:


24

Ответ на ваш вопрос может быть на уровне кода, протокола или архитектуры. Я попытаюсь суммировать здесь большинство проблем уровня протокола, так как это обычно имеет решающее значение в анализе плюсов и минусов. Имейте в виду, что OAuth2 - это намного больше, чем учетные данные владельца ресурса, которые, согласно спецификации, существуют по «устаревшим или миграционным причинам», считаются «более рискованными, чем другие типы предоставления», и в спецификации прямо указывается, что клиенты и серверы авторизации «СЛЕДУЕТ минимизировать использование этого типа гранта и использовать другие типы грантов, когда это возможно».

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

Пользовательские потоки аутентификации

В спецификации OAuth2 определены четыре роли. С примерами они являются:

  1. Владелец ресурса: пользователь, имеющий доступ к некоторому ресурсу, например, в вашем случае, разные пользователи могут иметь разный уровень доступа к REST API;
  2. Клиент: обычно приложение, которое использует пользователь, и ему необходим доступ к ресурсу для предоставления услуг пользователю;
  3. Ресурсный сервер: REST API в вашем случае; и
  4. Сервер авторизации: сервер, на котором представлены учетные данные пользователя и который будет аутентифицировать пользователя.

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

OAuth2 также позволяет использовать один сервер авторизации с несколькими клиентами и для нескольких ресурсов. Например, сервер ресурсов может принять аутентификацию пользователя через Facebook (который может выступать в качестве сервера авторизации в таком случае). Поэтому, когда пользователь запускает приложение (то есть клиент), оно отправляет пользователя в Facebook. Пользователь вводит свои учетные данные в Facebook, и клиент получает «токен», который он может представить серверу ресурсов. Сервер ресурсов просматривает токен и принимает его после проверки того, что Facebook фактически выдал его, и разрешает пользователю доступ к ресурсу. В этом случае клиент никогда не видит учетные данные пользователя (то есть их учетные данные Facebook).

Но предположим, что вы управляете идентификацией своего пользователя (и имеете сервер авторизации) вместо Facebook, который уже предоставляет токены вашему клиенту. Теперь предположим, что у вас также есть партнер, и вы хотите, чтобы его приложение (т.е. клиент) получило доступ к вашему REST API. При базовой аутентификации (или даже ROPC) пользователь предоставит учетные данные этому клиенту, который отправит их на сервер авторизации. Сервер авторизации затем предоставит токен, который может использоваться клиентом для доступа к ресурсам. К сожалению, это означает, что учетные данные пользователя теперь видны и этому клиенту. Однако вы не хотели бы, чтобы приложение партнера (которое могло быть внешним по отношению к вашей организации) даже знало пароль пользователя. Это проблема безопасности сейчас. Для достижения этой цели,

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

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

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

Выпуск токена

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

Есть еще один аспект OAuth2, который связан с тем, как токены выпускаются и как они работают. Когда пользователь предоставляет учетные данные серверу авторизации (даже в ROPC), сервер авторизации может предоставить один или несколько из двух типов токенов: 1) токен доступа и 2) токен обновления.

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

Когда клиент предоставляет токен доступа серверу ресурсов, он просматривает токен и после проверки заглядывает внутрь токена, чтобы определить, разрешить ли доступ или нет. Пока токен доступа действителен, клиент может продолжать его использовать. Допустим, пользователь закрывает приложение и запускает его на следующий день, а срок действия маркера доступа истек. Теперь клиент выполнит вызов на сервер авторизации и представит токен обновления, предполагая, что срок его действия не истек. Сервер авторизации, поскольку он уже выдал токен, проверяет его и может определить, что пользователю не нужно повторно предоставлять учетные данные, и, таким образом, предоставляет другой токен доступа клиенту. Теперь клиент снова имеет доступ к серверу ресурсов. Именно так обычно клиентские приложения для Facebook и Twitter запрашивают учетные данные один раз, а затем не требуют, чтобы пользователь снова вводил учетные данные. Этим приложениям никогда не нужно знать учетные данные пользователей, и, тем не менее, они могут получать доступ к ресурсам каждый раз, когда пользователь запускает приложение.

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

JWT - это просто формат токенов, который обычно используется с OAuth2 и OpenID Connect. Методы подписания токена и его проверки также стандартизированы с помощью библиотек, доступных для каждого сервера ресурсов, реализующего еще одно решение. Таким образом, преимущество заключается в возможности повторного использования кода, который был проверен и продолжает поддерживаться.

Последствия для безопасности

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

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

Вывод

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

Обратите внимание, что я не учел ваш комментарий о том, как учетные данные отправляются по проводной связи, потому что они могут быть защищены с использованием TLS или аналогичного протокола, или подтверждения владения и т. Д. Как кто-то уже предлагал, кодировка base 64 - это 0 безопасности, пожалуйста, не быть обманутым этим. Различия, упомянутые выше, обычно находятся на архитектурном уровне, и именно на этом я сосредоточился, потому что архитектура сложнее всего изменить после реализации.

Azure Active Directory B2C Basic , служба, над которой я работаю и недавно выпущенная для публичного просмотра, позволяет стороннему приложению использовать AAD в качестве сервера авторизации с возможностью взаимодействия с социальными ВПЛ (такими как Facebook, Google и т. Д.). Это также позволяет пользователям создавать свои собственные учетные записи вместо использования социальных IDP, которые впоследствии могут быть использованы для аутентификации. Есть несколько других сервисов, подобных этому (например, другой, о котором я знаю, это auth0) которые могут быть использованы разработчиками для полного аутсорсинга аутентификации и управления пользователями для своих приложений и ресурсов. Те же характеристики протоколов, которые я упомянул выше, используются разработчиками для разделения сервера авторизации (AAD), ресурса (например, их API REST), клиента (например, их мобильных приложений) и пользователей. Я надеюсь, что это объяснение поможет несколько.


Спасибо за широкий угол, но я не думаю, что эти преимущества (a) letting the user agent hold just the token instead of the password, (b) allowing a password change without disrupting existing client apps, (c) allowing users log out other sessionsхарактерны для потоков аутентификации токена. Ни базовая аутентификация, ни аутентификация токенов не упоминают функции (b) и (c) в своих спецификациях. Реализация (b) и (c) представляется возможной для любого вида аутентификации. Это будет связано с отслеживанием паролей (желательно их хэшей). Преимущество (а), кажется, зависит от более широкой области действия пароля.
угорь,

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

3

Я полагаю, что вы дезинформированы о шифровании вокруг переменных GET в URL

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

Только DNS-запрос, основанный на домене, на который отправляется HTTPS-запрос, не шифруется. Все остальное, порты, переменные GET, идентификатор ресурса, зашифрованы.

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


3

Обычная аутентификация не является хорошим способом защиты вашего REST API. Я объяснил причины почему в этом ответе .

Когда вы создаете REST API, вы реализуете сервер ресурсов в терминах OAuth2. Все, что нужно вашему API - это проверить, что токен, переданный вместе с запросом в HTTP-заголовке авторизации , действителен и принадлежит доверенному издателю. Смотрите эту ссылку, чтобы узнать, как реализовать проверку, если нет доступной библиотеки.

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

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

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

Все зависит от того, какого клиента вы используете.

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


1

Это либо безопасно, либо не безопасно. Ни больше ни меньше. Наличие base64 не делает Basic Auth (или что-либо еще) более безопасным.

Нет ничего плохого в отправке чего-нибудь незашифрованного, если он использует зашифрованный канал, такой как Https.

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


0

Я думаю, что вы должны понять терминологию в первую очередь. Вы сравниваете- Авторизация и Цифровая подпись

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

Какой механизм авторизации использовать, он более или менее зависит от вашего варианта использования.

Вот что можно найти на StackOverflow здесь :

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

И вот еще одна интересная статья, сравнивающая два.

Базовая аутентификация через SSL на самом деле довольно ответственна с точки зрения упрощенной безопасности. Когда мы сталкиваемся с именами пользователей и паролями, базовая аутентификация является распространенным решением, поскольку ее очень легко реализовать. Передача учетных данных зашифрована по протоколу SSL, а использование заголовка «Авторизация» является повсеместным в клиентах и ​​системах HTTP.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.