Spring Oauth2. Password encoder is not set in DaoAuthenticationProvider
Spring Oauth2. Password encoder is not set in DaoAuthenticationProvider
我对Spring Oauth和Spring Security还比较新。我正在尝试在我的项目中使用client_credentials流程。目前,我已经成功地使用自定义的CustomDetailsService从已经存在于我的系统中的数据库中获取client_id和密码(secret)。唯一的问题是,我无法更改AuthorizationServer使用的DaoAuthenticationProvider中的密码编码器-它默认设置为PlaintextPasswordEncoder。我无法配置它,以便例如使用SHAPasswordEncoder。它始终使用明文编码器。我可能对流程的理解还不够深入,因为我是Spring的新手。
以下是我的一些代码(具有不起作用的DaoAuthenticationProvider配置):
SecurityConfig.java
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String RESOURCE_ID = "restservice";
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/register/**");
}
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService());
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
return daoAuthenticationProvider;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new ShaPasswordEncoder();
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private MyCustomClientDetailsService myCustomClientDetailsService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore());
}
@Bean
public ResourceServerTokenServices defaultTokenServices() {
final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setTokenStore(tokenStore());
return defaultTokenServices;
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(myCustomClientDetailsService);
}
@Bean
public MyCustomClientDetailsService detailsService() {
return new MyCustomClientDetailsService();
}
}
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
...
}
}
自定义的ClientDetailsService类:
public class MyCustomClientDetailsService implements ClientDetailsService {
@Autowired
private UserService userService;
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
User fan = userService.getFan(clientId);
if (fan == null) {
throw new NoSuchClientException("No client with requested id: " + clientId);
}
BaseClientDetails details = new BaseClientDetails(clientId, restservice, "write", "client_credentials", "USER");
details.setClientSecret(fan.getEncodedPassword());
return details;
}
}
从我的UserService中获取的encodedPassword始终是一个错误的凭据,因为DaoAuthenticationProvider默认设置为PlaintextPasswordEncoder。
我错过了什么吗?
在这里使用的用于检查凭据的DaoAuthenticationProvider中是否可以设置密码编码器?还是我必须编写自己的AuthenticationProvider来按照我想要的方式进行检查?
Spring Oauth2的问题是由于在DaoAuthenticationProvider中没有设置密码编码器导致的。解决方法是在配置文件中设置密码编码器,并确保在创建用户时使用相同的密码编码器加密密码。
在XML配置中,可以使用以下配置来设置密码编码器:
在Java配置中,可以使用以下代码设置密码编码器:
@Bean public PasswordEncoder passwordEncoder() { return new StandardPasswordEncoder(); }
需要注意的是,在创建用户时,需要使用相同的密码编码器对密码进行加密。
另外,还可以在DaoAuthenticationProvider中设置密码编码器,如下所示:
@Bean public DaoAuthenticationProvider daoAuthenticationProvider() { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(userDetailsService); provider.setPasswordEncoder(passwordEncoder); return provider; }
然而,问题出现在尝试在DaoAuthenticationProvider中设置密码编码器时,它根本没有被设置,这是我调试时发现的。我知道在创建用户时需要使用相同的编码器,但这不是问题的原因。
因此,可以通过在配置文件中设置密码编码器,并确保在创建用户时使用相同的编码器来解决此问题。
问题的原因是在DaoAuthenticationProvider中未设置密码编码器。解决方法是在AuthorizationServerConfigurerAdapter的configure方法中覆盖configure方法,并在其中设置密码编码器。另外,还需要在WebSecurityConfigurerAdapter的configure(AuthenticationManagerBuilder auth)方法中设置密码编码器,以确保用户密码也能被正确编码。
具体代码如下:
public class MyAuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter { private PasswordEncoder passwordEncoder; // ... @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.passwordEncoder(passwordEncoder); } // ... } public class MyWebSecurityConfigurer extends WebSecurityConfigurerAdapter { private UserDetailsService userDetailsService; private PasswordEncoder passwordEncoder; // ... @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder); } // ... }
感谢提供解决方案。我已经寻找了几周了。