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

Авторизация и аутентификация 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?

4b9b3361

Ответ 1

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

Тем не менее, мы обычно используем схему, где каждый "ключ API" имеет две части: несекретный ID (например, 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,
  • клиент знает правильный пароль