gpt4 book ai didi

java - 如何将盐传递给 Spring?

转载 作者:行者123 更新时间:2023-11-30 10:29:59 27 4
gpt4 key购买 nike

我正在 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) 获取盐。我无法弄清楚如何配置该源。

最佳答案

找不到办法,因此实现了我自己的 PasswordEncoder 并使用静态变量从 UserDAO 传递盐:

public class PasswordEncoderImpl implements PasswordEncoder {

public static Constants constants = new Constants();

@Override
public String encode(CharSequence rawPassword) {
return DigestUtils.sha256Hex(rawPassword.toString());
}

@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
String salt = constants.getSalt();

/**
* If salt is null, it means the value in constants object is empty now.
* => client-secret validation is going on
* => we just need the comparision of plain-text string.
*/
if(salt != null) {
// case of password authentication
return DigestUtils.sha256Hex(salt + rawPassword).equalsIgnoreCase(encodedPassword);
} else {
//case of client-secret authentication
return rawPassword.equals(encodedPassword);
}
}
}

loadUserByUsername 方法中设置常量对象的值。

关于java - 如何将盐传递给 Spring?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43800710/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com