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

Широкая аутентификация с помощью sessionId или имени пользователя + пароля

У меня не так много опыта в инфраструктурах проверки подлинности Java и в процессе проверки подлинности в целом (только некоторые теоретические знания), поэтому для образовательных целей я пытаюсь создать этот тип аутентификации для моего HTTP-приложения:

  • Клиент отправляет логин + пароль на /login.
  • Широ регистрирует пользователя по заданным учетным данным. Сервер возвращает клиенту свой sessionId.
  • Клиент запрашивает какой-то ресурс /myresource?sessionId=1234567.
  • Сиро регистрируется в Субъекте по заданному sessionId. Затем сервер выполняет обычный рабочий процесс получения /myresource (с правами доступа на уровне метода управления Shiro).

В основном у меня есть следующие вопросы:

  • Думаю, мне не нужны сеансы HTTP и сеансы сервлета. У Сиро есть собственный менеджер сеансов, которого достаточно для моих нужд. Я не прав?
  • Является ли хорошей практикой предоставление клиенту реального sessionId или я должен отправить какой-то сеансToken (который разрешен для sessionId на стороне сервера)?
  • Как мне войти в Subject с помощью sessionId (который клиент должен хранить локально)?
  • Есть ли какие-либо другие вещи, которые мне нужно знать, прежде чем выполнять такую ​​проверку подлинности?

Спасибо заранее.

4b9b3361

Ответ 1

Думаю, мне не нужны сеансы HTTP и сеансы сервлета. У Сиро есть собственный менеджер сеансов, которого достаточно для моих нужд. Я не прав?

Нет, ты прав. Вот почему Сиро потрясающий. Из документация:

Поддержка сеанса Shiro намного проще в использовании и управлении, чем любой из этих двух механизмов [web container или EJB Stateful Session Beans], и он доступен в любом приложении независимо от контейнера.

например.

Subject currentUser = SecurityUtils.getSubject();    
Session session = currentUser.getSession();
session.setAttribute( "someKey", someValue);

цитата из документ: getSession calls work in any application, even non-web applications

Является ли хорошей практикой предоставление клиенту реального sessionId или мне нужно отправить какой-то сеансToken (который разрешен для sessionId на стороне сервера)?

Плохая идея отправить простой sessionId. Специально, если вы отправляете данные по незашифрованной сети. Либо используйте что-то вроде HTTPS или используйте что-то строку NONCE.

И, обратите внимание, если по http/s POST-данным вместо того, чтобы иметь его в URL-адресе.

Как мне войти в тему Subject с помощью sessionId (который клиент должен хранить локально)?

Вы имели в виду, как бы вы могли аутентифицировать тему, когда у вас есть идентификатор сеанса? Вы можете просто, из документа,

Subject requestSubject = new Subject.Builder().sessionId(sessionId).buildSubject();

Есть ли еще какие-то другие вещи, которые мне нужно знать, прежде чем выполнять такую ​​проверку подлинности?

Да.


Обновление

Об этой части проверки подлинности объекта - будет ли она создавать вновь созданный объект subject, прошедший проверку подлинности? Если нет, как мне сделать это "текущим" объектом?

Если вы говорите о new Subject.Builder().sessionId(sessionId).buildSubject(), это не будет. И я не знаю, как установить его как currentUser для потока. Shiro JavaDoc говорит,

[this way] return Объект Subject не привязан автоматически к приложению (потоку) для дальнейшего использования. То есть SecurityUtils.getSubject() не будет автоматически возвращать тот же экземпляр, что и возвращаемый компоновщиком. Разработчик фреймворка привязывает построенный объект для дальнейшего использования, если это необходимо.

так, это до вас, как вы привязываете тему в текущем потоке или далее используете.

Если вы беспокоились о том, как работает SecurityUtils.getSubject(); thingy, в контексте веб-контейнера он использует простой файл cookie для хранения ваших данных сеанса. Когда ваш запрос поступает через фильтр Сиро, он привязывает текущего субъекта к запросу на его жизненный цикл (текущий поток). И когда вы как getSubject(), он просто получает запрос Subject от запроса. Я нашел интересную тему здесь.

about nonce part: Если он отправит мне какой-то хэш вместо его sessionId - я не смогу его декодировать, чтобы получить реальный sessionId (чтобы разрешить ему это). Я что-то пропустил здесь?

Nonce part - это боль в шее. Теперь передумав, я думаю, что NONCE просто переборщил. Позвольте мне объяснить, в любом случае,

  • Пользователь регистрируется в первый раз с именем пользователя и паролем. Установите userid, nonce (скажем, UUID) и HASH(sessionID+nonce), назовите его hash1 на стороне клиента. Скажем, в печенье. Храните этот nonce на стороне сервера, может быть в БД или на карте как user_id <--> nonce,session_id

  • При последующем запросе убедитесь, что вы прошли обратно userid, nonce и HASH.

  • На стороне сервера первое, что вы сделаете, это проверить запрос. Получите sessionId и nonce, хранящиеся в hashmap или DB на основе user_id, которые были отправлены клиентом. Создайте хэш, HASH (sessionId_from_db + nonce_from_db), назовите его hash2.

  • Теперь, если hash1 соответствует hash2, вы можете проверить запрос, и поскольку вы сохранили текущий sessionId на стороне сервера, вы можете его использовать. По завершении запроса установите новое значение nonce в файле cookie и на стороне сервера.

Если вы пройдете через 1 - 4, вы поймете, что вам не понадобится Сиро для аутентификации. (: Итак, я возвращаю свои слова, NONCE не применяется в этом случае, если вы не слишком увлекаетесь безопасностью по производительности.

Почему MITM нападает на меня? Мой клиент (javascript ajax code) извлекает данные с сервера через ajax. Поэтому я не думаю, что я должен заботиться о MITM в любом случае.

Я думаю, это будет важно для вас. MITM Attack означает, что ваши запросы/ответы приковываются к машине через MITM (маршрутизатор). Если это незашифрованный запрос, все это текст в MITM. Он может видеть все ваши просьбы... и, возможно, подменять запросы и может заблокировать сеанс. позвольте мне найти пример... http://michael-coates.blogspot.com/2010/03/man-in-middle-attack-explained.html