因此,我可以使用标准CURL获得访问令牌,但是一旦我尝试获取访问令牌,应用程序就会抛出“IllegalStateException - UserDetailsService Required'”。据我所知,一旦刷新令牌,我们就不需要再次验证用户详细信息了吗?但无论如何它应该在那里,因为它必须首次验证访问令牌。
见下面我的Oauth2配置:
@Configuration
public class OAuth2Config {
@Configuration
@EnableResourceServer
protected static class ResourceServiceConfig extends ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/oauth/token/").permitAll()
.antMatchers(HttpMethod.GET, "/api/**").access("#oauth2.hasScope('read')")
.antMatchers(HttpMethod.OPTIONS, "/api/**").access("#oauth2.hasScope('read')")
.antMatchers(HttpMethod.POST, "/api/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.PUT, "/api/v1/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.PATCH, "/api/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.DELETE, "/api/**").access("#oauth2.hasScope('write')");
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.resourceId(<RESOURCE ID>)
.tokenStore(tokenStore);
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Value("${oauth.clientid}")
private String CLIENT_ID;
@Value("${oauth.clientsecret}")
private String CLIENT_SECRET;
@Value("${oauth.tokenvalidity}")
private String VALIDITY_SECONDS;
@Autowired
private DataSource dataSource;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(tokenStore())
.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.withClient(CLIENT_ID)
.scopes("read", "write")
.authorities(Authorities.USER)
.authorizedGrantTypes("password", "refresh_token")
.secret(CLIENT_SECRET)
.accessTokenValiditySeconds(Integer.parseInt(VALIDITY_SECONDS));
}
}
}
和Web安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests().anyRequest().permitAll();
}
}
所以是的,这个似乎没有意义,因为1.当我们尝试刷新令牌授权时,为什么它甚至会用于用户详细信息服务? 2.为什么当它显然存在并且事先为密码授权工作时,它无法找到用户详细信息服务?
由于
答案 0 :(得分:0)
我将此作为另一个内部类添加到我的Oauth配置类中,并从Web Security Config类中删除了任何身份验证管理器/密码编码器配置,实际上目前唯一剩下的就是配置上的@Override( HttpSecurity http)功能。
@Configuration
@Order(Ordered.LOWEST_PRECEDENCE - 20)
protected static class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private CustomUserDetailsService userDetailsService;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
}
作为解决方案的作者注释&#34;全局身份验证配置在之后在Spring Boot中命令(因此这里的设置会覆盖Boot中的设置)。&#34;虽然他也提到这在春季启动1.2.3中不会成为一个问题,但是现在这就是我需要让它工作并找到我的UserDetailsService。
答案 1 :(得分:0)
在AuthorizationServerConfig类中:
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenStore(tokenStore())
.userDetailsService(userDetailsService);
}
答案 2 :(得分:0)
我正在使用Spring Boot + OAuth2,并且遇到相同的异常
IllegalStateException - UserDetailsService Required
。
我正在用内存身份验证管理器进行测试。我解决如下
WebSecurityConfig(扩展了WebSecurityConfigurerAdapter)-清除默认的bean UserDetailsService
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Bean("userDetailsService")
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean(); //default
}
// other logics
}
OAuth2ServerConfig(扩展了AuthorizationServerConfigurerAdapter)-将UserDetailsService bean注入oAuth2配置
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
private UserDetailsService userDetailsService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenStore(tokenStore)
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
.userDetailsService(userDetailsService); //inject here
}
// other logics
}