Как выполнить аутентификацию без сохранения состояния (без сеанса) и без файлов cookie?
Боб использует веб-приложение, чтобы чего-то достичь. А также:
- Его браузер на диете, поэтому он не поддерживает куки.
- Веб-приложение является популярным, оно в данный момент работает с большим количеством пользователей - оно должно хорошо масштабироваться. Поскольку поддержание сеанса будет накладывать ограничение на количество одновременных подключений и, конечно, принесет немалое снижение производительности, нам может потребоваться система без сеансов:)
Некоторые важные замечания:
- у нас есть транспортная безопасность (HTTPS и его лучшие друзья);
- За кулисами веб-приложение делегирует множество операций внешним службам от имени текущего пользователя (эти системы распознают Боба как одного из своих пользователей) - это означает, что мы должны переслать им учетные данные Боба.
Теперь, как мы аутентифицируем Боба (при каждом запросе)? Какой разумный способ реализовать такую вещь?
- играя в теннис с учетными данными через скрытые поля формы HTML... мяч содержит учетные данные (имя пользователя и пароль), а две ракетки - это браузер и веб-приложение соответственно. Другими словами, мы можем передавать данные туда и обратно через поля формы, а не через куки. При каждом веб-запросе браузер публикует учетные данные. Хотя в случае одностраничного приложения это может выглядеть как игра в сквош против резиновой стены вместо игры в теннис, поскольку веб-форма, содержащая учетные данные, может сохраняться в течение всего времени жизни веб-страницы (и сервера). будет настроен, чтобы не предлагать учетные данные обратно).
- хранение имени пользователя и пароля в контексте страницы - переменные JavaScript и т. д. Здесь требуется одна страница, ИМХО.
- аутентификация на основе зашифрованных токенов. В этом случае действие входа в систему приведет к генерации зашифрованного токена безопасности (имя пользователя + пароль + что-то еще). Этот токен будет возвращен клиенту, и к последующим запросам будет добавлен токен. Имеет ли это смысл? У нас уже есть HTTPS...
- другие...
- В крайнем случае: не делайте этого, храните учетные данные в сеансе! Сессия это хорошо. С или без печенья.
Возникает ли какое-либо беспокойство по поводу Интернета / безопасности относительно какой-либо из ранее описанных идей? Например,
- тайм-аут - мы можем сохранить отметку времени вместе с учетными данными (отметка времени = время, когда Боб ввел свои учетные данные). Например, когда NOW - timestamp> threshold, мы можем отклонить запрос.
- Межсайтовая защита скриптов - не должна отличаться ни в коем случае, верно?
Большое спасибо, что нашли время, чтобы прочитать это:)
2 ответа
Ах, я люблю эти вопросы - поддержание сессии без сессии.
Я видел несколько способов сделать это во время моих испытаний во время оценки приложений. Один из популярных способов - игра в теннис, о которой вы упомянули, - отправка имени пользователя и пароля в каждом запросе для аутентификации пользователя. Это, на мой взгляд, небезопасно, особенно если приложение не является одной страницей. Это также не масштабируется, особенно если вы хотите добавить авторизацию к вашему приложению в дополнение к аутентификации в будущем (хотя я думаю, что вы могли бы также создать что-то на основе логинов)
Один популярный, хотя и не полностью сохраняющий состояние механизм (при условии, что у вас есть выполнение JavaScript) - это вставка cookie сессии в JavaScript. Парень из службы безопасности во мне кричит на это, но на самом деле это может сработать - каждый запрос имеет X-Authentication-Token
заголовок или что-то в этом роде, и вы сопоставляете это с базой данных, хранилищем файлов в памяти и т. д. в бэкэнде для проверки пользователя. Этот токен может иметь тайм-аут любого времени, которое вы указали, и если он истекает, пользователь должен снова войти в систему. Он достаточно масштабируемый - если вы храните его в базе данных, с одним выполненным оператором SQL и с правильными индексами, выполнение может занять очень мало времени, даже при одновременном использовании нескольких пользователей. Хотя нагрузочное тестирование здесь определенно поможет. Если я правильно прочитал вопрос, это был бы ваш механизм зашифрованных токенов - хотя я настоятельно рекомендовал бы использовать криптографически случайный токен, скажем, 32 символа, а не комбинацию имени пользователя + пароль + что-либо еще - таким образом, он остается непредсказуемо, но вы все равно можете связать его с идентификатором пользователя или чем-то подобным.
Что бы вы ни использовали, убедитесь, что оно отправлено вам безопасно. HTTPS защищает вас по сети, но не защищает вас, если вы пропускаете токен сеанса через URL (или, что еще хуже, учетные данные через URL). Я бы порекомендовал использовать заголовок или, если это невозможно, каждый раз отправлять токен через POST-запрос (это означало бы скрытое поле формы в браузере пользователя.) Последний подход с использованием POST-запроса должен использовать защиту CSRF, просто в случае, хотя я подозреваю, что использование самого токена могло бы быть своего рода защитой CSRF.
Наконец, что не менее важно, убедитесь, что у вас есть какой-то механизм в бэкэнде для очистки устаревших токенов. В прошлом это было проклятием многих приложений - быстро растущей базы данных токенов аутентификации, которая, кажется, никогда не исчезнет. Если вам нужно поддерживать несколько пользовательских входов, убедитесь, что вы либо ограничиваете количество, либо имеете более короткое время для каждого токена. Как я уже говорил, нагрузочное тестирование может быть ответом на это.
Я могу подумать о некоторых других проблемах безопасности, но они слишком широки, чтобы их можно было рассмотреть на данном этапе - если вы помните все случаи использования (и злоупотребления), вы, вероятно, сможете сделать довольно хорошую реализацию эта система.
Насчет входа в систему - я думаю, что обычно вы хотите поддерживать сеансы также для гостей.
Так что, если вы хотите принудительно выполнить вход, опция шифрованного токена может быть полезной. Это может быть полезно и для гостевой сессии. В другом направлении я бы совмещал добавление токена к URL и вариант с теннисом.
Обратите внимание, что отправка учетных данных только в URL может быть опасной. Например, вы можете пропустить токен через заголовок реферера HTTP или даже кого-то, кто просто проверяет ваш трафик или смотрит ваш компьютер.
Другое дело, что даже если бы вы могли использовать куки-файлы, я бы порекомендовал вам добавить случайный токен или случайный верификатор, чтобы обезопасить себя от атак на сайты подделки запросов (CSRF).