3

Ситуация:
Java EE веб-приложение «помни меня» автоматический логин, сделанный правильно?

  • ява EE веб-приложений с проверкой подлинности пользователя на основе имени пользователя/пароля
  • проверка пароля не производится самим приложением. Он использует HttpServletRequest.login(), а область безопасности определена на сервере приложений.
  • Приложение использует авторизацию (@RolesAllowed аннотацию)
  • Приложение позволяет пользователю иметь в виду, так что ему не нужно аутентифицировать каждый раз

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

1 Просто держать HttpSession открытым
На самом деле это был мой предпочтительный способ в первую очередь. Я думал, что использование HttpSessioin.setMaxInactiveInterval() сделает трюк. В основном это происходит, но если сеансы не очищены должным образом, и у вас много пользователей, это может быть проблемой ресурсов. мой собственный вопрос, чтобы показать, что очистка HttpSession непросто все время.

2 Использование «запомнить меня» печенье
Почему не просто генерировать UUID и отправить его в печенье и чем проверить это, когда HttpSession новый. Это работает очень хорошо, если единственное, что используется для области безопасности, это проверить имя пользователя/пароль. Если авторизация или функции, такие как getUserPrincipal(), используются, то это невозможно. Я не нашел способ использовать HttpServletRequest.login() или аналогичную функцию с токеном вместо пароля.

3 Использование «запомнить меня» печенье и использовать мое собственное разрешение
Ну, конечно, это возможно, но мне нравится простой способ ограничить доступ к некоторым бобам или методам. Это затрудняет мне реализацию чего-то, когда пользователь может получить доступ к чему-то, чего он не должен.

4 Использование «запомнить меня» печенье с паролем в нем
Stupid! Следующий!

5 Использование «запомнить меня» печенье и сохранить пароль
Идея заключается в том, чтобы вспомнить пароль и отношение к для печенья, так HttpServletRequest.login() может быть использован с паролем. Это метод, описанный в этой Ответ: https://stackoverflow.com/a/5083809/210380
Я думаю, что этот метод имеет большую проблему: Никогда не храните пароли в незашифрованном виде
Можно было бы подумать о просто держать пароли в памяти, но мне не нравится, что либо. Приложение можно использовать где угодно, и я не хочу быть ответственным, если все пароли компании просочились, потому что кто-то получил временный доступ к серверу и сделал дамп памяти.

Мое текущее решение
Исходя из этих мыслей я пришел с моим собственным решением. Я использую два куки. Первый - это просто «помнить меня» cookie с строковым представлением UUID. Этот UUID также запоминается в памяти или в базе данных вместе с именем пользователя. Второй файл cookie также содержит строковое представление UUID и используется для шифрования пароля. Зашифрованный пароль запоминается вместе с UUID первого файла cookie в базе данных или в памяти. UUID из второго файла cookie не сохраняется. Нет в базе данных или в памяти. Чтобы шифровать и расшифровывать пароль пользователя, я использую StandardPBEStringEncryptor from jasypt.
Когда пользователь пытается повторно аутентифицировать эти куки-файлы, я прочитал их как для поиска имени пользователя, так и для зашифрованного пароля на основе первого файла cookie, дешифрования пароля со второго файла cookie и использования HttpServletRequest.login() с именем пользователя и паролем. Затем я удаляю зашифрованный пароль, хранящийся на сервере, и перезапускаю процесс с двумя новыми UUID.

Вопросы

  1. Есть ли действительно не стандартизированы решение для этого?

  2. Есть ли проблемы с безопасностью в моем решении, которые я не вижу?
    , например. может ли быть неразумно шифровать пароль с помощью нового ключа при повторной аутентификации

  3. Является ли стандартнымPBEStringEncryptor хорошим выбором для этой задачи?

  4. Является ли мое решение излишним, и я трачу свое время?

Благодаря

+0

Вы нашли лучшее решение для этого? – Ced

+0

Нет, я все еще использую его вот так. – raffael

ответ

0
  1. Там действительно нет стандарта "запомнить меня" в сервлет API.
  2. Я считаю, что ваше решение более уязвимо для кражи файлов cookie, так как ваш второй UUID используется для шифрования пароля и хранится в файле cookie. This answer показывает, что обычно хранится в файле cookie для входа.
  3. Нужно ли двустороннее шифрование? Одностороннее шифрование намного проще и проще в обращении. В зависимости от ваших требований безопасности приложений все, что находится выше SHA-512, является подходящим алгоритмом хеширования.
  4. Я бы порекомендовал вам взглянуть на Apache Shiro. Он поддерживает, помните меня, соленое хеширование паролей с несколькими алгоритмами (только в одном направлении, но я не уверен) и @RolesAllowed-подобных перехватчикам безопасности.

Если вы идете на Широ, this tutorial действительно тщательный и полный. Вы также можете проверить официальную документацию на shiro.apache.org