Как безопасно поддерживать аутентификацию пользователя через сторонний API?

Я создаю webapp, который позволяет пользователям создавать, редактировать и сохранять документы. База данных учетных записей пользователей контролируется отдельно, и мне предоставлен API SOAP, который скажет мне, действительно ли данное имя пользователя / пароль.

Предполагая, что имя пользователя / пароль действительны, API вернет мне следующую информацию:
• адрес электронной почты
• имя пользователя
• login_number (уникальный идентификатор для учетной записи, как представляется, является auto-increment int)

Я буду хранить данные для своего приложения в своей собственной базе данных, поэтому я, вероятно, буду использовать login_number для связывания данных с отдельными пользователями.

Мой вопрос заключается в том, как я должен отслеживать пользователя, как только пользователь успешно выполнит вход. Хранение файла login_number как файла cookie будет работать, но похоже, что это будет ужасно неуверенно для меня. Я думаю что-то вроде файла cookie, хранящего какой-то случайный хеш с таблицей поиска, хранящей этот хеш и связанный с ним номер входа, но я не уверен, что этого достаточно.

Помечено с PHP / MySQL, поскольку это конец, с которым я планирую работать, но не уверен, что это действительно важно для этого вопроса.

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

Итак, есть несколько способов:

  1. Положитесь на поставщика : если на основе User-Id API SOAP предоставляет информацию о том, вошел ли пользователь в систему или нет. Вы можете просто использовать этот вызов перед выполнением любой задачи, требующей аутентификации.
  2. Постройте свою собственную аутентификацию поверх SOAP API : это то, что вы планируете делать, я думаю. Подход заключается в использовании зашифрованного / хэшированного и трудновоспроизводимого токена.
    Идея идет так

    (a) Как только пользователь регистрируется в создании уникального токена, сохраните этот токен в сеансе пользователя или в каком-то постоянном хранилище. Может быть в memcache или где-то сопоставлен с userId. В принципе, везде, где вы можете получить этот токен, вы знаете, с каким пользователем он связан.

    (b) Храните этот токен в качестве файла cookie.

    (c) Всякий раз, когда вы хотите пройти аутентификацию, используйте маркер из файла cookie, чтобы он соответствовал токену, сохраненному в сеансе пользователя (или вытащил идентификатор пользователя, соответствующий токену, и сопоставил текущий userId с userId, вытащил с помощью токена для проверки).

    (d) удалить файл cookie при выходе из системы.

    Теперь есть хорошие шансы на то, что человек-в-середине приложит такой подход.

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

Надеюсь это поможет.


Nonce Идея nonce проста и очень прочная. Но я не уверен, что это применимо к вашему делу. Это в основном для защиты вызовов SOAP. AWS использует аналогичную вещь.

  1. Предоставьте клиенту secretKey .
  2. Всякий раз, когда запрос запрашивает запрос, он должен передать хэш текущей метки времени с secretKey (скажем, token ) и метку времени, которую он использовал для создания token .
  3. Сервер проверяет token , сравнивая token с хешем, который создает сервер, используя отметку времени, переданную в заголовке, и секретный ключ, хранящийся в другом месте, на стороне сервера, может быть в базе данных в виде пароля или secretKey.
  4. Если жетоны совпадают, пользователю разрешен доступ к другому.
  5. Кроме того, сервер может также отключить доступ, если временная метка слишком отключена от текущей метки времени сервера.

Этот подход эффективно свободен от атаки MITM, но не уверен, подходит ли вам этот подход.

Диалог клиентского сервера выглядит так:

 client ----request timestamp --------> server <---current timestamp -----------' --- {ts: timestamp, token: Hash256(timestamp, secretKey)} --> isEqual(token, hash256(ts, secretKey)) | | Access Denied<- false/ true --> ACCESS 

@kramthegram спасибо, что напомнил Nonce

Вы можете попробовать хэшировать номер пользователя с помощью nonce . Установите, чтобы файл cookie истекал по длительности таймаута входа (скажем, 30 минут). Случайный сеанс nonce поможет предотвратить атаки, когда злоумышленник может скопировать ваш файл cookie, чтобы получить доступ, поскольку каждый сеанс имеет чувствительный к времени хеш.