有没有教程或没有人有指示如何使用Spring-Security做以下事情?Spring Security自定义身份验证和密码编码
任务:
我需要从我的数据库认证的用户名得到盐,并用它来加密提供的密码(从登录页面),将其与存储的加密密码(又名认证用户)。
附加信息:
我使用自定义的数据库结构。一个UserDetails
对象是通过自定义UserDetailsService
创建的,该自定义对象使用自定义DAOProvider从数据库获取信息。
我security.xml
文件至今:
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
</authentication-provider>
</authentication-manager>
现在我想我需要
<password-encoder hash="sha" />
但还有什么?我如何告诉spring security使用数据库提供的盐来编码密码?
编辑:
我发现This SO后是informatative但不是充分的:如果我在XML定义盐源由密码编码器一起使用,例如:
<password-encoder ref="passwordEncoder">
<salt-source ref="saltSource"/>
</password-encoder>
我将不得不编写一个自定义SaltSource来使用我的自定义盐。但是这不是在UserDetails
对象内部找到的。所以......
选择1:
我可以使用的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"/>
备选方案2:
否则我不得不注入我accountDAO到SaltSource
提取盐从数据库中给定的userName
。
但是:Spring Security如何调用SaltSource
?始终与saltSource.getSalt(userDetails)
?
然后,我只需要确保我的SaltSource
在我的accountDAO
上使用userDetails.accountName
来检索盐。
EDIT2:
刚刚得知,我的做法是..遗留.. :(所以我想我就用StandardPasswordEncoder
(我仍然要弄清楚如何准确使用)
顺便说一句:我实现了第一个选项,用一个自定义的UserDetails类来扩展User类,然后添加一个salt属性,然后将它作为userPropertyToUse传递给SaltSource,就像它在SO后面提到的那样在编辑1 ...
编辑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版本等列出的版本)。此外,文件谈到了春季安全3.1,所以我认为,我会随之而去。
当创建一个用户(对我来说只有一个管理员可以做到这一点),我只是用
StandardPasswordEncoder encoder = new StandardPasswordEncoder();
String result = encoder.encode(password);
和我做。
Spring Security将随机创建一个salt并将其添加到密码字符串中,然后将其存储在数据库中,所以不再需要salt column。
人们可以但是也可以提供一个全球性的盐作为构造函数的参数(new StandardPasswordEncoder("12345");
),但我不知道如何设置我的安全配置,以检索一个bean是价值,而不是与<constructor-arg name="secret" value "12345" />
提供静字符串。但是我不知道需要多少。
您的文章真的帮助我,我有非常类似的问题。 +1自我解决^^ – user1431729
我会建议BCryptPasswordEncoder而不是StandardPasswordEncoder。在安全性和与其他语言的互操作性方面,BCryptPasswordEncoder是更好的选择 – Farm