Spring Security自定义身份validation和密码编码

有没有教程或有没有人有关于如何使用Spring-Security做以下指示?

任务:

我需要从我的数据库中获取validation用户名的salt,并使用它来对提供的密码(从login页面)进行encryption,以便将其与存储的encryption密码(也就是对用户进行身份validation)进行比较。

附加信息:

我使用自定义的数据库结构。 UserDetails对象是通过自定义的UserDetailsService创build的,而UserDetailsService则使用自定义的DAOProvider从数据库中获取信息。

我的security.xml文件到目前为止:

 <authentication-manager> <authentication-provider user-service-ref="userDetailsService"> </authentication-provider> </authentication-manager> 

现在我想我会需要

  <password-encoder hash="sha" /> 

但还有什么? 如何告诉spring安全使用数据库提供的salt来编码密码?


编辑

我发现这个SOpost是信息性的,但不够:如果我在我的xml中定义一个盐密码源以供密码编码器使用,如下所示:

  <password-encoder ref="passwordEncoder"> <salt-source ref="saltSource"/> </password-encoder> 

我将不得不写一个自定义SaltSource来使用我的自定义盐。 但是这不是在UserDetails对象内部find的。 所以…

备选案文1:

我可以使用自定义UserDetails的实现,然后可能有salt属性?

 <beans:bean id="saltSource" class="path.to.MySaltSource" p:userPropertyToUse="salt"/> 

 @Service("userDetailsService") public class UserDetailsServiceImpl implements UserDetailsService { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { // ... return buildUserFromAccount(account); } @Transactional(readOnly = true) UserDetailsImpl buildUserFromAccount(Account account){ // ... build User object that contains salt property } 

自定义用户类别:

 public class UserDetailsImpl extends User{ // ... private String salt; public String getSalt() { return salt; } public void setSalt(String salt) { this.salt = salt; } } 

security.xml文件:

 <authentication-manager> <authentication-provider user-service-ref="userDetailsService"> <password-encoder hash="sha"> <salt-source ref="saltSource"/> </password-encoder> </authentication-provider> </authentication-manager> <beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource" p:userPropertyToUse="salt"/> 

备选案文2:

否则,我不得不将我的accountDAO注入到SaltSource ,从数据库中为给定的userName提取salt。

但是:Spring Security如何调用SaltSource ? 总是与saltSource.getSalt(userDetails)

然后,我只需要确保我的userDetails.accountName在我的accountDAO上使用accountDAO来检索salt。


EDIT2:

刚刚了解到我的方法是..遗产.. :(所以我想我只使用StandardPasswordEncoder (我仍然要弄清楚如何使用)。

顺便说一句:我实现了第一个选项与一个自定义的UserDetails类扩展用户类,只是添加一个盐属性,然后将其作为一个userPropertyToUse传递给SaltSource,就像在编辑1中提到的SO后提出的…


编辑3:

刚刚获得了StandardPasswordEncoder的工作,所以我会留下一些指针:

使用StandardPasswordEncoder进行身份validation:

 <beans:bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder"> </beans:bean> <authentication-manager> <authentication-provider user-service-ref="userDetailsService"> <password-encoder ref="encoder" /> </authentication-provider> </authentication-manager> 

这需要版本3.1.0.RC中的spring-security-crypto模块? 我所知道的。 找不到任何具有3.0的存储库。 版本(即使它包含3.0.6等列出的版本)。 另外文件谈到了Spring 3.1的安全问题,所以我想,我会继续这样做。

当创build一个用户(我只有一个pipe理员可以做到这一点),我只是使用

  StandardPasswordEncoder encoder = new StandardPasswordEncoder(); String result = encoder.encode(password); 

我完成了。

Spring Security会随机创build一个salt并将其添加到密码string中,然后将其存储到数据库中,这样就不再需要salt列了

但是,我们也可以提供一个全局salt作为构造参数( new StandardPasswordEncoder("12345"); ),但我不知道如何设置我的安全性configuration来从bean中检索该值,而不是提供静态string<constructor-arg name="secret" value "12345" /> 。 但是我不知道需要多less。

我将这个标记为答案,因为我解决了我的问题,没有给出任何其他意见或答案:

编辑1 – select1回答原来的问题

但是我必须知道,定制密码salting是Spring Security 3.1中不需要的传统方法,正如我在

编辑3在那里我留下了一些关于如何使用StandardPasswordEncoder来存储密码的自动化Salts的指针。

为了什么是值得的,我写了这篇博客文章,详细描述了你所描述的内容: http : //rtimothy.tumblr.com/post/26527448708/spring-3-1-security-and-salting-passwords

要从bean中检索全局salt,请使用Springexpression式语言或SpEL。

 <beans:bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder"> <constructor-arg value="#{someotherBean.somePropertyWithAGetterMethod"/> </beans:bean>