it-swarm.com.ru

Аутентификация для REST веб-сервисы

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

  • OAuth

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

  • OpenID

OpenID, безусловно, предоставляет решение для аутентификации, но это больше направлено на то, чтобы пользователи могли использовать свои сторонние учетные данные (Google, Yahoo и т.д.). Хотя я хотел бы поддержать это, для меня это не является главной задачей, и я буду Определенно разрешить пользователям регистрироваться с использованием собственных учетных данных (адрес электронной почты/пароль).

  • Базовая аутентификация HTTP

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

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

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


Помимо создания веб-служб, я также буду создавать клиентское (веб-приложение), которое использует эти службы от имени пользователя, но я не хочу, чтобы приложение должно было хранить информацию о пользователе/​​учетные данные/и т.д. Итак, как то так:

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

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

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

Мои самые высокие требования:

  • Безопасно (очевидно)
  • Родные полномочия
  • Поддержка сторонних учетных данных (Google, Yahoo, LinkedIn и т.д.)
  • Поддержка нескольких клиентов (веб-приложение, мобильное приложение, сторонние приложения и т.д.)
  • Учетные данные клиента (просто идентификатор приложения?)
  • Сеансы входа, срок действия которых истек
  • Авторизация НЕ требуется 

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

Правка:

Я думаю, что мне нужно будет реализовать следующее: 

1) Собственные учетные данные/токены (базовая аутентификация HTTP через SSL?) 

2) OpenID «Проверяющая сторона», позволяющая моему API-интерфейсу использовать OpenID, размещенные в других местах (т. Е. «Поддержка учетных данных третьих сторон»)

3) OAuth "Consumer", позволяющий моему api получать доступ к сторонним сервисам (например, доступ к профилю LinkedIn пользователя). 

4) OpenID «Провайдер», позволяющий людям использовать собственные идентификаторы API в другом месте (необязательно) 

5) OAuth-провайдер, позволяющий сторонним приложениям получать доступ к моему API от имени пользователя (необязательно) 

Это кажется правильным, или я делаю это более сложным, чем это должно быть?

42
user2943799

Вы можете рассмотреть JWT (JSON Web Token), см. JWT черновик rfc . Это, безусловно, будет соответствовать вашим требованиям безопасности и истечения сеанса. Однако, будучи черновым стандартом, вряд ли будет широко использоваться сейчас, это может скоро измениться, поскольку JWT является частью OAuth 2.0. JWT легко реализовать на большинстве языков, и уже существует множество библиотек. В качестве простого объяснения токен JWT состоит из 3 частей: заголовка, тела и подписи. Заголовок и тело являются объектами json, которые закодированы в basee64url (алфавиты отличаются от base64 на 2 последних символа), а затем подписаны HMAC256 (или другим алгоритмом, указанным в заголовке), в RFC объясняется, как именно генерировать эту подпись. Возможно, вы захотите проверить этот онлайн генератор токенов .

JWT - это заголовки http и параметры запроса.

12
nullptr

Один из хороших вариантов - «Аутентификация с общим ключом». Этот тип аутентификации использует веб-служба Amazon и служба хранилища Windows Azure. Мы использовали Аутентификацию по общему ключу в сервисе REST, который мы разработали. Вы можете сделать быстрый поиск в Google для «аутентификации по общему ключу», вы получите много деталей. 

Я написал одно сообщение в блоге здесь об этом.

Шаги высокого уровня:

  1. Клиент объединяет набор уникальных данных (элементов), определенных службой REST.
  2. Подписать эти объединенные данные с помощью ключа, известного только клиенту и службе REST
  3. Отправьте эту подпись службе REST в качестве значения для заголовка HTTP
  4. Служба REST вычисляет подпись точно так же, как клиент
  5. Сравните подпись, отправленную клиентом, с вычисленной, если она совпадает с действительным запросом, иначе отклоните запрос
11
Anu Thomas Chandy

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

Внешнее приложение будет хранить токен и предоставлять его при каждом последующем запросе.

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

Маркер может быть связан с исходным IP-адресом для дополнительной безопасности.

Токен может быть передан как cookie или как один из параметров запроса в URL.

Если беспокоит проверка подлинности клиента SSL, вы можете использовать взаимную проверку подлинности SSL. Каждому клиенту должен быть предоставлен сертификат, которому доверяет сервер. Это может быть один и тот же сертификат или разные сертификаты, если вам приходится обращаться с клиентами по-разному.

7
ArunasR

Исходя из ваших требований, я думаю, что OAuth 2.0 может быть интересным вариантом. OAuth действительно является протоколом авторизации, но он также Authenticates клиент с clientId и clientSecret. Вы можете использовать Client Credential Flow и решили не включать Refresh Token, таким образом, у пользователя есть Access Token, срок действия которого истекает через определенное время. А поскольку OAuth является широко используемым протоколом, для вас и ваших клиентов уже есть множество библиотек на стороне клиента и сервера.

Если вы думаете, что OAuth слишком тяжелый или слишком сложный для вашего приложения, я, вероятно, остановлюсь на Basic Authentication вместо HTTPS. Но, как я уже говорил в другом ответе на подобный вопрос, я бы никогда не изобрел свой собственный механизм аутентификации.

Для получения дополнительной информации вы также можете взглянуть на другой ответ, который я дал ранее на аналогичный вопрос: https://stackoverflow.com/a/15003777/849741

2
Jos Vinke

Вы можете использовать HTTP Basic Auth, где переданный пароль на самом деле не пароль, а токен, который клиент получил по другому запросу на ресурс, где он/она/она должен был предоставить свой пароль один раз и только один раз ( возможно даже по другому каналу). Это не защищает атаки типа «человек посередине» (так как здесь нет подписи сообщений), но идея в том, что вы всегда можете потребовать, чтобы клиент каким-то образом сгенерировал динамический токен (то есть для собственной службы аутентификации), а затем пусть он отправит этот токен в качестве замены пароля, чтобы фактический пароль не передавался постоянно по проводам ………. Да, это похоже на одно из «пользовательских решений аутентификации», но на самом деле это не так, потому что вы можете навязать то, что когда-либо правил, которые вы хотите на токене-пароле, например, использование токена подписи в качестве пароля, который привязан к сеансу или пересчитывается при каждом запросе (без разделения каких-либо секретов), чтобы сервер мог проверить сообщение - какими бы ни были ваши потребности. идея состоит в том, чтобы отправить проверочный токен в качестве «пароля» запроса HTTP Basic Auth и не полагаться на более сложные протоколы, не исключая их (по вашему выбору).

1
Kai

Я реализовал и выпустил в качестве открытого источника базовую службу, которая позволяет аутентификацию, ее можно легко изменить, чтобы при необходимости можно было войти в систему из трех кортежей. Ему около 2 лет, и он написан на Java поверх Spring, поэтому вы можете пересмотреть технологию, но она работает, и вы можете получить общее представление о том, как это делается. Найти его здесь на Google или следовать мои сообщения в блоге об этом. Обратите внимание, что приложение больше не загружается на облачных пчелах, но если вы настроите его в своей учетной записи, все должно быть в порядке.

1
TheZuck

Я предлагаю использовать Spring Boot для ваших веб-сервисов RESTful, потому что тогда вы сможете использовать их Spring Security для реализации вашей собственной пользовательской аутентификации на основе их шаблонов. Вы можете реализовать свою собственную аутентификацию путем расширения или реализации их базовых классов безопасности и интерфейсов соответственно. У вас также есть возможность включить другой механизм аутентификации, который вы перечислили в Spring Boot, если это необходимо.

0
Ramil