REST API авторизация и аутентификация (веб + мобильный) - PullRequest
69 голосов
/ 22 февраля 2012

Я читал об oAuth, API Amazon REST, HTTP Basic / Digest и т. Д., Но не могу собрать все это в один кусок. Вероятно, это самая близкая ситуация - Создание API для мобильных приложений - Аутентификация и авторизация

Хотелось бы построить API-ориентированный сайт - сервис. Поэтому (в начале) у меня будет API в центре, а веб-сайт (PHP + MySQL) будет подключаться через cURL , Android и iPhone через их сетевые интерфейсы. Итак, 3 основных клиента - 3 ключа API. И любой другой разработчик может также разрабатывать через интерфейс API, и они получат свой собственный ключ API. Действия API будут приниматься / отклоняться в зависимости от статуса userLevel. Если я являюсь администратором, я могу что-либо удалять и т. Д., Все остальные могут манипулировать только своими локальными (учетными) данными.

Во-первых, авторизация - я должен использовать oAuth + xAuth или мою реализацию типа «что-то вроде меня» (см. http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/RESTAuthentication.html?r=9197)? Как я понимаю, на пользователь сервиса Amazon == API пользователь ( есть ключ API) . На моем сервисе мне нужно разделить стандартных пользователей / учетную запись (того, кто зарегистрирован на сайте) и учетные записи разработчиков (у которых должен быть свой ключ API).

Итак, сначала мне нужно авторизовать ключ API , а затем Аутентифицировать пользователя . Если я использую схему Amazon для проверки ключей API разработчика (авторизирую их приложение), какую схему мне следует использовать для аутентификации пользователя?

Я прочитал о получении токена через api.example.org/auth после (через HTTPS , HTTP Basic) размещения моего имени пользователя и пароля и затем пересылаю его при каждом следующем запросе. Как управлять токенами, если я вошел в систему одновременно на Android и веб-сайте ? А как насчет атаки «человек посередине», если я использую SSL только при первом запросе (при передаче имени пользователя и пароля) и только HTTP при каждом другом? Разве это не проблема в этом примере Защита паролем службы REST?

1 Ответ

123 голосов
/ 22 февраля 2012

Как всегда, лучший способ защитить ключ - не передавать его.

При этом мы обычно используем схему, где каждый «ключ API» состоит из двух частей: несекретного идентификатора (например, 1234) и секретного ключа (например, байта [64]).

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

Теперь, когда потребитель первый получает доступ к вашему API, чтобы подключиться, попросите его

  • Отправка параметра "username" ("john.doe" не секрет)
  • Отправка параметра «APIkeyID» («1234», не секрет)

и верните ему

  • соли из вашей базы данных (в случае, если один из параметров неверен, просто верните немного повторяемой соли - например. sha1 (имя пользователя + "notverysecret").
  • метка времени сервера

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

Потребитель теперь должен рассчитать соленые хэши API-ключа и пароля. Таким образом, потребитель получает те же хеши для пароля и API-ключа, что и в вашей базе данных, но без каких-либо секретов.

Теперь, когда потребитель впоследствии получает доступ к вашему API, чтобы выполнить реальную работу, попросите его

  • Отправка параметра "username" ("john.doe" не секрет)
  • Отправка параметра «APIkeyID» («1234», не секрет)
  • Отправка параметра "RequestSalt" (байт [64], случайный, не секретный)
  • Отправить параметр «RequestTimestamp» (рассчитывается по времени клиента и известному смещению)
  • Отправка параметра "RequestToken" (хеш (хеш пароля + запрос_сальта + request_timestamp + apikeyhash))

Сервер не должен принимать временные метки больше, чем, скажем, 2 секунды в прошлом, чтобы обезопасить себя от атаки с повтором.

Сервер теперь может вычислять тот же хеш (passwordhash + request_salt + request_timestamp + apikeyhash), что и клиент, и быть уверенным, что

  • клиент знает ключ API,
  • клиент знает правильный пароль
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...