Авторизация и аутентификация API REST (web + mobile)

Я читал о oAuth, API 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 разработчика (авторизуйте их приложение), какую sheme следует использовать для аутентификации пользователя?

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

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

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

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

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

  • Отправьте параметр «имя пользователя» («john.doe» не секрет)
  • Отправьте параметр «APIkeyID» («1234», а не секрет)

и вернуть его

  • соли из вашей базы данных (если один из параметров неверен, просто верните некоторую повторяемую соль – например, sha1 (имя пользователя + «notverysecret»).
  • Временная метка сервера

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

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

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

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

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

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

  • клиент знает ключ API,
  • клиент знает правильный пароль