是否有一个教程或有没有人指出如何使用Spring-Security执行以下操作?
Task:
我需要从我的数据库中获取用于验证用户名的salt并使用它来加密提供的密码(从登录页面)以将其与存储的加密密码(a.k.a . 验证用户)进行比较 .
additional information:
我使用自定义数据库结构 . UserDetails
对象是通过自定义 UserDetailsService
创建的,后者又使用自定义DAOProvider从数据库中获取信息 .
到目前为止我的 security.xml
文件:
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
</authentication-provider>
</authentication-manager>
现在我想我需要
<password-encoder hash="sha" />
还有什么?如何告诉spring security使用databaseprovided salt来编码密码?
edit :
我发现This SO帖子有信息但不够:如果我在我的xml中定义一个盐源来供密码编码器使用,如下所示:
<password-encoder ref="passwordEncoder">
<salt-source ref="saltSource"/>
</password-encoder>
我'll have to write a custom SaltSource to use my custom salt. But that'在 UserDetails
对象中找不到 . 所以...
Alternative 1:
我可以使用可能具有salt属性的UserDetails的自定义实现吗?
<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"/>
Alternative 2:
否则,我必须将我的accountDAO注入 SaltSource
,从数据库中提取给定 userName
的盐 .
但是:Spring Security如何调用 SaltSource
?总是与 saltSource.getSalt(userDetails)
?
然后我只需要确保我的 SaltSource
在 accountDAO
上使用 userDetails.accountName
来检索盐 .
Edit2:
刚刚得知我的方法是..遗产.. :(所以我想我只会使用 StandardPasswordEncoder
(我仍然需要弄清楚如何使用) .
顺便说一句:我实现了第一个选项,其中一个自定义UserDetails类扩展了User类,只是添加了一个salt属性,然后将其作为userPropertyToUse传递给SaltSource,就像它在编辑1中提到的SO帖子中提出的那样...
EDIT 3:
刚刚使用了StandardPasswordEncoder,所以我将在这里留下一些指示:
使用StandardPasswordEncoder进行身份验证:
<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,所以我想,我将继续这样做 .
在创建用户时(对我来说只有管理员可以这样做),我只是使用
StandardPasswordEncoder encoder = new StandardPasswordEncoder();
String result = encoder.encode(password);
我已经完成了
Spring安全性会随机创建一个salt并将其添加到密码字符串中,然后将其存储在数据库中,以便 no salt column is needed anymore .
但是,也可以提供全局salt作为构造函数参数( new StandardPasswordEncoder("12345");
),但我不知道如何设置我的安全配置以从bean中检索该值,而不是使用 <constructor-arg name="secret" value "12345" />
提供静态字符串 . 但我不知道还需要多少钱 .
3 回答
我将此标记为已回答,因为我解决了我的问题并且没有给出任何其他评论或答案:
Edit 1 - Alternative 1 回答原始问题
BUT 我必须了解自定义密码salting是Spring Security 3.1中不再需要的遗留方法,正如我在
Edit 3 我在这里指出了如何使用
StandardPasswordEncoder
来自动存储密码的Salts .对于's worth, I wrote this blog post detailing what you'描述的内容:http://rtimothy.tumblr.com/post/26527448708/spring-3-1-security-and-salting-passwords
要从bean检索全局salt,请使用Spring Expression Language或SpEL .