因此,我可以使用标准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.为什么当它显然在那里并且事先为密码授权工作时,它无法找到用户详细信息服务?
谢谢
3 回答
在这里找到答案:https://github.com/spring-projects/spring-security-oauth/blob/master/tests/annotation/jdbc/src/main/java/demo/Application.java#L136
我将此作为另一个内部类添加到我的Oauth配置类中,并从Web Security Config类中删除了任何身份验证管理器/密码编码器配置,实际上目前唯一剩下的就是配置上的@Override(HttpSecurity http)功能 .
正如解决方案的作者评论“全局认证配置在Spring Boot中命令之后(因此这里的设置覆盖了Boot中的设置)” . 虽然他也提到这不会是 Spring 季启动1.2.3中的问题,但是现在这就是我需要让它工作并找到我的UserDetailsService .
在AuthorizationServerConfig类中:
我正在使用Spring boot OAuth2,并遇到同样的异常
IllegalStateException - UserDetailsService Required
.我正在使用内存身份验证管理器进行测试 . 我解决了如下