Подтвердить что ты не робот

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

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

  • OAuth

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

  • OpenID

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

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

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

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

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


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

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

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

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

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

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

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

EDIT:

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

1) Собственные учетные данные/токены (HTTP basic auth over SSL?)

2) OpenID "Relying Party", чтобы позволить api использовать OpenID, размещенные в другом месте (т.е. "поддержка сторонних учетных данных" )

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

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

5) Поставщик OAuth, чтобы позволить сторонним приложениям получать доступ к моему api от имени пользователя (необязательно)

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

  • Клиент объединяет набор уникальных данных (элементов), определенных службой REST.
  • Подпишите эти комбинированные данные с помощью ключа, известного только клиенту и службе REST
  • Отправьте эту подпись службе REST как значение для заголовка HTTP
  • Служба REST вычисляет подпись точно так же, как клиент сделал
  • Сравнить подпись, отправленную клиентом с одной, вычисленной, если таковая же принимает его действительный запрос, иначе отклонить запрос

Ответ 3

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

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

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

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

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

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

Ответ 4

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

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

Для получения дополнительной информации вы также можете посмотреть на другой ответ, который я дал ранее на аналогичный вопрос: fooobar.com/questions/133588/...

Ответ 5

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

Ответ 6

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

Ответ 7

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

Ответ 8

OAuth 2.0 - это то, что вам нужно, если вам требуется только авторизация. Вы можете использовать OpenID Connect, который обеспечивает аутентификацию и поддерживает OAuth2.0 для авторизации. Для OepnID Connect доступно множество сертифицированных продуктов, если вам нужно настроить сервис самостоятельно, есть также много онлайн-сервисов.