【发布时间】:2017-10-03 16:27:09
【问题描述】:
我正在 Spring Boot 中实施 OAuth 2.0。当用户传递他的用户名/密码时,spring 会尝试通过对密码进行散列并将其与我传递给它的已经散列的密码进行比较来对其进行身份验证。但是,Spring 总是错过了盐,所以它总是返回错误的凭据。
如何将盐传递给 Spring?
这是我的 UserDAO 类:
@Service
public class UserDAO implements UserDetailsService, SaltSource{
private LoginDetails user;
private UserDetailsImpl userDetailsImpl;
@Autowired
private LoginDetailsManager loginDetailsManager;
@Override
public UserDetails1 loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("Get user");
user = loginDetailsManager.getByUsername(username);
System.out.println(user.toString());
if (user == null) {
throw new UsernameNotFoundException(
"User " + username + " not found.");
}
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_USER");
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
grantedAuthorities.add(grantedAuthority);
String password = user.getPasswordHash();
String salt = user.getSalt();
userDetailsImpl = new UserDetailsImpl(user.getUsername(), user.getPasswordHash(), salt, grantedAuthorities);
return new UserDetailsImpl(
user.getUsername(),
user.getPasswordHash(),
salt,
grantedAuthorities);
}
}
以下是我的 AuthorizationServer 类:
@Configuration
@EnableAuthorizationServer
protected class AuthorizationApplication extends AuthorizationServerConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new StandardPasswordEncoder();
}
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AuthenticationManager authenticationManager;
@Bean
protected AuthorizationCodeServices getAuthorizationCodeServices() {
return new JdbcAuthorizationCodeServices(dataSource);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
AuthorizationCodeServices services = getAuthorizationCodeServices();
JdbcTokenStore tokenStore = getTokenStore();
endpoints
.userDetailsService(userDetailsService)
.authorizationCodeServices(services)
.authenticationManager(authenticationManager)
.tokenStore(tokenStore)
.approvalStoreDisabled();
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients();
security.passwordEncoder(passwordEncoder);
}
通过一点调试,我发现 Spring 从 SaltSource (org.springframework.security.authentication.dao.SaltSource) 获取它的盐。我无法弄清楚如何配置该来源。
【问题讨论】:
-
因为我的数据库中有 SHA256(hash+password) - 我从 UserDAO 类返回到 Spring 作为 UserDetailsImpl 对象的属性
user.getPasswordHash()。 Spring 正在将其与 SHA256(密码)进行比较,我未经授权。 -
对不起,我没听懂。目前,我有一个手动填充的数据库进行测试。如果没有盐,spring 将如何进行身份验证?
-
好的,请多多包涵。为了避免复杂性,我刚刚创建了一个实现 PasswordEncoder 的新类(使用两种方法 - 用于简单 sha256 散列的编码和 match())并开始使用它而不是 StandardPasswordEncoder。有没有办法为此配置 SaltSource?
-
我正在实现
PasswordEncoder,但在DaoAuthenticationProvider类中,我发现:与加密模块PasswordEncoder 一起使用时,Salt 值必须为空。不再执行它没有意义。有没有其他方法可以解决这个问题? -
如果您使用 BCryptPasswordEncoder,那么您不必担心加盐,因为它会自动加盐您的密码。
标签: java spring spring-boot spring-security oauth-2.0