论坛首页 Java企业应用论坛

Spring Security 3.1.0中整合PasswordEncoder

浏览 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方法,这里不再赘述。

  
   发表时间:2012-03-01  
1. 命令名间里有配置 encoder的地方. 还有配置盐. 木有必要自己搞一个provider.

2. 保存用户的时候应该用一个encoder去加密(注入到UserDetailService中). 不要用静态方法, 静态方法写完了别人是没有办法重写的.
0 请登录后投票
   发表时间:2012-03-01  
tq02ksu 写道
1. 命令名间里有配置 encoder的地方. 还有配置盐. 木有必要自己搞一个provider.

2. 保存用户的时候应该用一个encoder去加密(注入到UserDetailService中). 不要用静态方法, 静态方法写完了别人是没有办法重写的.



1、命名空间里配置encoder我研究的不是很多,回头研究一下,感谢你提出这个建议。我在这里使用provider除了登录时验证加密密码以外,还有个验证用户输入的验证码的功能,在这里我给去掉了。

2、确实是个问题。当时考虑是为了在加密这里降低与Spring的耦合性,考虑到以后可能会换其它的加密方式。但是可能用静态方法确实是个问题。我会将其替换成接口的。
0 请登录后投票
   发表时间:2012-03-27  
楼主直接给源代码吧
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics