Аутентификация в Spring Security с зашифрованным паролем - PullRequest
6 голосов
/ 15 февраля 2012

Простое веб-приложение Spring Security с кодировкой пароля:

<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="personService">
     <security:password-encoder hash="md5" ref="passwordEncoder"> 
        <!--  <security:salt-source user-property="username"/> -->
     </security:password-encoder>
 </security:authentication-provider>
</security:authentication-manager>

Кодировка также проста:

 person.setPassword(encoder.encodePassword(person.getPassword(), null));

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

UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
                username, password);
Authentication authentication = authenticationManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(authentication);

Но теперь я получаю зашифрованный пароль из БД и не могу выполнить аутентификацию, как раньше.

Проблема.что Spring не знает, что пароль прибывает из UsernamePasswordAuthenticationToken уже закодирован.И он кодирует его во второй раз.Кто может помочь?

Редактировать

Итак, я вижу здесь два решения:

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

Любые другие?Что лучше?

1 Ответ

10 голосов
/ 16 февраля 2012

Вы на самом деле не сказали, что идет не так, но код аутентификации должен быть точно таким же, как и для нехэшированной версии.

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

Убедитесь, что:

  1. Вы используете значение нехэшированного пароля, когдасоздание UsernamePasswordAuthenticationToken
  2. Значение в базе данных действительно совпадает с хешем, созданным кодировщиком.Загрузите его сами и проверьте в тесте.База данных может хранить его в верхнем регистре, например.

Кроме того, вам, вероятно, следует выбрать что-то лучше, чем обычный MD5.Возможно, вы захотите взглянуть на bcrypt, например, который поддерживается в Spring Security 3.1 и автоматически использует случайное солт-значение.

Обновление

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

Просто проверьте URL-адреса электронной почты, загрузите информацию для этого пользователя и создайте Authentication объект для них:

UserDetails user = ... // load user here
Authentication a = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(a);
...