Аутентификация Широ с помощью sessionId или имени пользователя + пароля - PullRequest
15 голосов
/ 14 декабря 2011

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

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

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

  1. Я думаю, яне нужно ни сеансов HTTP, ни сеансов сервлетов.У Широ есть собственный менеджер сессий, которого достаточно для моих нужд.Я не прав?
  2. Это хорошая практика, чтобы дать клиенту реальный sessionId или я должен отправить какой-то sessionToken (который разрешен в sessionId на стороне сервера)?
  3. Как мне войти в системуСубъект использует sessionId (который клиент должен хранить локально)?
  4. Есть ли еще что-то, что мне нужно знать перед выполнением такого рода аутентификации?

Заранее спасибо.

1 Ответ

33 голосов
/ 16 декабря 2011

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

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

Поддержка сеанса Shiro намного проще в использовании и управлении, чем любой из этих двух [веб-контейнеров или 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 или я должен послать какой-то sessionToken (который разрешен в sessionId на стороне сервера)?

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

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

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

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

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

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

Да.

  1. Чтение Управление сеансами Широ
  2. Отклонение от Атака MITM
  3. О HTTPS и SSL
  4. Некоторые функции Hash this , Apache Commons DigestUtils и могут быть this

Обновления

Об этой части аутентификации субъекта - сделает ли вновь созданный Субъект субъектом, прошедшим проверку подлинности в настоящее время?Если нет, то как мне сделать его «текущим» субъектом?

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

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

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

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

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

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

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

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

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

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

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

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

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

...