浏览 6230 次
精华帖 (0) :: 良好帖 (3) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-02-29
最后修改:2012-02-29
"Spring Security 3.1 中功能强大的加密工具 PasswordEncoder"一文中,我介绍了Spring Security 3.1.0中推出的新的密码加密工具PasswordEncoder,有很多同学问道如何整合到项目中,在此另开一贴,专门讲一下这个问题。主要讲如何在登录时验证加密密码。
在这里采用自定义provider方式。 在spring security配置文件中,增加如下代码: <authentication-manager> <!--自定义Provider--> <authentication-provider ref="daoAuthenticationProvider"> </authentication-provider> </authentication-manager> <b:bean id="daoAuthenticationProvider" class="com.DaoProvider"> <b:property name="userDetailsService" ref="securityManager" /> </b:bean> <b:bean id="securityManager" class="com.SecurityManager"> <b:property name="userServiceImpl" ref="userServiceImpl" /> </b:bean> 自定义Provider如下: public class DaoProvider extends AbstractUserDetailsAuthenticationProvider { private UserDetailsService userDetailsService; public UserDetailsService getUserDetailsService() { return userDetailsService; } public void setUserDetailsService(UserDetailsService userDetailsService) { this.userDetailsService = userDetailsService; } protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { String rawPassword = (String) authentication.getCredentials(); String passwd = userDetails.getPassword(); // 验证加密后的密码 if (!EncryptUtil.matches(rawPassword, passwd)) { throw new AuthenticationServiceException( messages .getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials")); } } @Override protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { UserDetails user = null; try { user = userDetailsService.loadUserByUsername(username); } catch (UsernameNotFoundException notFound) { throw notFound; } catch (AuthenticationException repositoryProblem) { throw new AuthenticationServiceException(repositoryProblem .getMessage(), repositoryProblem); } if (user == null) { throw new AuthenticationServiceException( "UserDetailsService returned null, which is an interface contract violation"); } return user; } } 自定义Provider继承自AbstractUserDetailsAuthenticationProvider抽象类,重写了additionalAuthenticationChecks和retrieveUser方法,additionalAuthenticationChecks是增加了对加密密码的验证,而retrieveUser是根据用户名获得用户。 在additionalAuthenticationChecks方法中,我们通过EncryptUtil来进行密码验证,如果验证失败,则抛出AuthenticationServiceException异常,异常的提示信息可以结合message本地化,spring默认的提示消息是 AbstractUserDetailsAuthenticationProvider.badCredentials。 当然,你也可以修改提示信息的内容,修改后,需要去spring security 3.0-core.jar包中找到org.springframework.security下的messages_zh_CN.properties文件。默认的是 引用 AbstractUserDetailsAuthenticationProvider.badCredentials=您输入的用户名或者密码错误!
com.SecurityManager类实现了Spring security的UserDetailService接口 import org.springframework.security.core.userdetails.UserDetailsService; public class SecurityManager implements UserDetailsService { @Override public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException { User user = //从数据库中来取 if (user == null) throw new UsernameNotFoundException("User " + userName + " has no GrantedAuthority"); return user; } //实现其它方法 } 通过如上配置,可以实现登录时,验证密码是否正确。 新建用户时,密码加密使用EncryptUtil.encrypt方法,这里不再赘述。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-03-01
1. 命令名间里有配置 encoder的地方. 还有配置盐. 木有必要自己搞一个provider.
2. 保存用户的时候应该用一个encoder去加密(注入到UserDetailService中). 不要用静态方法, 静态方法写完了别人是没有办法重写的. |
|
返回顶楼 | |
发表时间:2012-03-01
tq02ksu 写道 1. 命令名间里有配置 encoder的地方. 还有配置盐. 木有必要自己搞一个provider.
2. 保存用户的时候应该用一个encoder去加密(注入到UserDetailService中). 不要用静态方法, 静态方法写完了别人是没有办法重写的. 1、命名空间里配置encoder我研究的不是很多,回头研究一下,感谢你提出这个建议。我在这里使用provider除了登录时验证加密密码以外,还有个验证用户输入的验证码的功能,在这里我给去掉了。 2、确实是个问题。当时考虑是为了在加密这里降低与Spring的耦合性,考虑到以后可能会换其它的加密方式。但是可能用静态方法确实是个问题。我会将其替换成接口的。 |
|
返回顶楼 | |
发表时间:2012-03-27
楼主直接给源代码吧
|
|
返回顶楼 | |