使用密码编码的简单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。他正在第二次编码。 谁可以帮忙?
修改
所以我在这里看到两个解决方案:
还有其他人吗?什么是最好的?
答案 0 :(得分:10)
您实际上并未说出错误,但验证码应与非散列版本完全相同。
如果数据库中有散列密码且相应的编码器注入认证提供程序,则编码器将对用户提供的密码进行散列,然后再与数据库版本进行比较。
确保:
UsernamePasswordAuthenticationToken
另外,你应该选择比普通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);