Ответ на ваш вопрос может быть на уровне кода, протокола или архитектуры. Я попытаюсь суммировать здесь большинство проблем уровня протокола, так как это обычно имеет решающее значение в анализе плюсов и минусов. Имейте в виду, что OAuth2 - это намного больше, чем учетные данные владельца ресурса, которые, согласно спецификации, существуют по «устаревшим или миграционным причинам», считаются «более рискованными, чем другие типы предоставления», и в спецификации прямо указывается, что клиенты и серверы авторизации «СЛЕДУЕТ минимизировать использование этого типа гранта и использовать другие типы грантов, когда это возможно».
Есть все еще много преимуществ использования ROPC по сравнению с базовой аутентификацией, но прежде чем мы углубимся в это, давайте разберемся с основным различием протокола между OAuth2 и базовой аутентификацией. Пожалуйста, потерпите меня, поскольку я объясню это и позже приеду в ROPC.
Пользовательские потоки аутентификации
В спецификации OAuth2 определены четыре роли. С примерами они являются:
- Владелец ресурса: пользователь, имеющий доступ к некоторому ресурсу, например, в вашем случае, разные пользователи могут иметь разный уровень доступа к REST API;
- Клиент: обычно приложение, которое использует пользователь, и ему необходим доступ к ресурсу для предоставления услуг пользователю;
- Ресурсный сервер: REST API в вашем случае; и
- Сервер авторизации: сервер, на котором представлены учетные данные пользователя и который будет аутентифицировать пользователя.
При запуске клиентского приложения ему предоставляется доступ к ресурсам на основе пользователя. Если у пользователя есть права администратора, ресурсы и операции, доступные пользователю в 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), клиента (например, их мобильных приложений) и пользователей. Я надеюсь, что это объяснение поможет несколько.