Как сделать аутентификацию без сохранения состояния (без сеанса) и без файлов cookie?

107

Боб использует веб-приложение, чтобы чего-то добиться. И:

  • Его браузер находится на диете, поэтому не поддерживает файлы cookie .
  • Веб-приложение популярно, оно работает с большим количеством пользователей в данный момент - оно должно хорошо масштабироваться . Пока сохранение сеанса будет налагать ограничение на количество одновременных подключений и, конечно же, приведет к значительному снижению производительности , мы могли бы иметь систему без сеанса :)

Некоторые важные примечания:

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

Теперь, как мы аутентифицируем Боба (по каждому запросу)? Что было бы разумным способом реализовать такую ​​вещь?

  • играть в теннис с учетными данными через скрытые поля HTML-формы ... мяч содержит учетные данные ( имя пользователя и пароль ), а две ракетки - это браузер и веб-приложение соответственно. Другими словами, мы можем передавать данные туда и обратно через поля формы, а не через файлы cookie. При каждом веб-запросе браузер публикует учетные данные. Хотя в случае одностраничного приложения это может выглядеть как игра в сквош против резиновой стены вместо игры в теннис , поскольку веб-форма, содержащая учетные данные, может быть сохранена в течение всего времени существования веб-страницы. (и сервер будет настроен так, чтобы не предлагать учетные данные обратно).
  • сохранение имени пользователя и пароля в контексте страницы - переменные JavaScript и т. д. Здесь требуется одностраничный, IMHO.
  • аутентификация на основе зашифрованных токенов. В этом случае действие входа в систему приведет к созданию зашифрованного токена безопасности (имя пользователя + пароль + что-то еще). Этот токен будет возвращен клиенту, и последующие запросы будут сопровождаться токеном. Имеет ли это смысл? У нас уже есть HTTPS ...
  • другие ...
  • В крайнем случае: не делайте этого, сохраните учетные данные в сеансе! Сессия хорошая. С файлами cookie или без них.

Возникает ли у вас какое-либо беспокойство по поводу Интернета или безопасности в связи с какой-либо из ранее описанных идей? Например,

  • тайм-аут - мы можем сохранить метку времени вместе с учетными данными (метка времени = время, когда Боб ввел свои учетные данные). Например, когда NOW - timestamp> threshold , мы можем отклонить запрос.
  • Защита межсайтового скриптинга - никак не должно отличаться, верно?

Спасибо, что нашли время прочитать это :)

Turdus-Merula
источник
2
Вы можете добавить токен к каждому URL-адресу. В ASP.NET для этого есть (устаревший) режим. Это доказывает, что это может работать.
usr
1
Где все? :)
turdus-merula
2
Я думаю, у вас есть довольно хорошее представление о доступных вариантах. Доверьтесь своим рассуждениям и решайте сами.
usr
Можно ли использовать такой плагин, как silverlight of flash?
Giu
@usr не уверен, что это хорошая идея, как если бы хакер проник в журналы вашего веб-сервера, мог украсть ваш токен и войти в вашу систему.
GibboK 04

Ответы:

74

Ах, мне нравятся эти вопросы - поддержание сеанса без сеанса.

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

Один популярный, хотя и не полностью без учета состояния (при условии, что у вас есть выполнение JavaScript), является встраивание файла cookie сеанса в JavaScript. Охранник во мне кричит на это, но это действительно может сработать - у каждого запроса естьX-Authentication-Tokenзаголовок или что-то в этом роде, и вы сопоставляете его с базой данных, хранилищем файлов в памяти и т. д. на бэкэнде, чтобы проверить пользователя. Этот токен может иметь тайм-аут любого указанного вами времени, и если он истечет, пользователю придется снова войти в систему. Он довольно масштабируемый - если вы храните его в базе данных, выполняя его один оператор SQL и с правильными индексами, он должен выполняться очень быстро, даже с несколькими одновременными пользователями. Хотя здесь определенно поможет нагрузочное тестирование. Если я правильно прочитал вопрос, это будет ваш механизм зашифрованного токена - хотя я настоятельно рекомендую вам использовать криптографически случайный токен, скажем, из 32 символов, вместо использования комбинации имени пользователя + пароля + чего-либо еще - таким образом, он остается непредсказуемо, но вы все равно можете связать его с идентификатором пользователя или чем-то в этом роде.

Что бы вы ни использовали, убедитесь, что оно отправлено вам безопасно. HTTPS защищает вас по сети, но не защищает в случае утечки токена сеанса через URL-адрес (или, что еще хуже, учетных данных через URL-адрес). Я бы рекомендовал использовать заголовок или, если это невозможно, отправлять токен через запрос POST каждый раз (это будет означать скрытое поле формы в браузере пользователя). Последний подход использования запроса POST должен использовать защиту CSRF, просто на всякий случай, хотя я подозреваю, что использование самого токена может быть своего рода защитой от CSRF.

И последнее, но не менее важное: убедитесь, что у вас есть какой-то механизм в бэкэнде для очистки просроченных токенов. В прошлом это было отравой для многих приложений - быстро растущая база данных токенов аутентификации, которая, кажется, никогда не исчезнет. Если вам нужно поддерживать несколько учетных записей пользователей, убедитесь, что вы ограничили их количество или установили более короткий временной лимит для каждого токена. Как я уже сказал, ответом на это может быть нагрузочное тестирование.

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

Картик Рангараджан
источник
Разве вы не делаете то, что делает игровой фреймворк, и отправляете подписанный файл cookie пользователю? Затем этот файл cookie отправляется обратно на сервер для каждого последующего запроса?
j будет
8
> Его браузер находится на диете, поэтому он не поддерживает файлы cookie.
Картик Рангараджан
4
Действительно ли какие-либо из этих предложений не имеют состояния / сеанса ? Из ваших пяти основных параграфов (по состоянию на 2013-12-19 издание поста): №1 вводный, №2 предлагает необычные сеансы Web2.0 ™ с приправой, №3 - просто наставления, №4 обсуждает последствия состояния , а № 5 - расплывчатый финал ... как это было принято ?? В лучшем случае это косвенно информативно!
JamesTheAwesomeDude
1

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

Итак, если вы хотите принудительно выполнить вход в систему, вариант зашифрованного токена может подойти. Это может быть хорошо и для гостевой сессии. В другом направлении я бы совмещал добавление токена к URL-адресу и опцию тенниса.

Обратите внимание, что отправка учетных данных только в URL-адресе может быть опасной. Например, у вас может произойти утечка токена через заголовок реферера HTTP или даже кем-то, кто просто проверяет ваш трафик или наблюдает за вашим компьютером.

Другое дело, даже если бы вы могли использовать файлы cookie, я бы порекомендовал вам добавить случайный токен или случайный верифер, чтобы защитить себя от атак с подделкой межсайтовых запросов (CSRF).

Гари Б.Н.
источник
3
Состояние сеанса хранится на сервере. Вопрос касается аутентификации без сохранения состояния.
Kwebble