Spring Security中的身份验证带有密码

时间:2012-02-15 18:19:37

标签: spring authentication spring-security md5

使用密码编码的简单Spring Security Web应用程序:

<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));

因此,在DataBase中,所有密码都将被编码。 现在我想在apllication中使用某个用户名对某些用户进行身份验证。 之前(当密码是纯文本时)就像这样:

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

但是现在我从DB获得了编码密码​​,并且不能像以前那样进行身份验证。

问题所在。 Spring不知道密码来自已编码的UsernamePasswordAuthenticationToken。他正在第二次编码。 谁可以帮忙?

修改

所以我在这里看到两个解决方案:

  1. 实现自定义DaoAuthenticationProvider,其中添加检查两个密码是否已经散列
  2. 实施自定义身份验证并手动将其置于安全上下文中。
  3. 还有其他人吗?什么是最好的?

1 个答案:

答案 0 :(得分:10)

您实际上并未说出错误,但验证码应与非散列版本完全相同。

如果数据库中有散列密码且相应的编码器注入认证提供程序,则编码器将对用户提供的密码进行散列,然后再与数据库版本进行比较。

确保:

  1. 您在创建UsernamePasswordAuthenticationToken
  2. 时使用未散列的密码值
  3. 数据库中的值实际上与编码器生成的哈希值相同。自己加载并在测试中检查它。例如,数据库可能以大写形式存储它。
  4. 另外,你应该选择比普通MD5更好的东西。例如,您可能希望查看bcrypt,它在Spring Security 3.1中受支持并自动使用随机salt值。

    <强>更新

    您建议创建一个接受散列密码的提供程序并不是一个好的建议。这将允许任何窃取密码哈希的人直接对其进行身份验证(从而首先破坏哈希的目的)。

    只需验证您的电子邮件网址链接,加载该用户的信息并为其创建Authentication对象:

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