![](/img/trans.png)
[英]Spring security OAuth2 Refresh Token - IllegalStateException, UserDetailsService is required
[英]Refresh token call fails using spring security an oauth2 with error: UserDetailsService is required
我正在使用 Spring Security OAuth2 进行授权。 尝试刷新令牌时,我收到一个错误: UserDetailsService is required
(有趣的是,我只在 unix 机器上而不是在 Windows 上收到此错误)。 我使用的是 Spring OAuth2 版本 2.0.7。
由于某种原因, DefaultTokenService
的AuthenticationManager
不是空的,它尝试验证用户以检查他是否仍然存在。 我认为它被初始化是因为一些 spring 安全与 spring oauth2 配置问题。
我没有使用任何自定义UserDetailsService
,因此此时它不应该对用户进行身份验证。 但是,当我调试它时,我发现它尝试使用WebSecurityConfigurerAdapter
一个并出现此错误。 即使我提供了我的自定义虚拟UserDetailsService
,它也没有使用那个,而是尝试使用另一个为空的。 我在这里错过了什么吗? 我不知道为什么会这样?
这是我的 Oauth2 配置
@Configuration
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private MySpringTokenStore tokenStore;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private MyClientDetailsServiceImpl clientDetailsService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore);
endpoints.authenticationManager(authenticationManager)
.approvalStoreDisabled();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients();
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
}
这是我的 Spring 安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/myRest/events/**", "/events/**", "/events", "/myRest/events").permitAll()
.antMatchers("/login.jsp", "/login").permitAll()
.and()
.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")).disable()
.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/myRest/events")).disable()
.sessionManagement().sessionFixation().none();
// @formatter:on
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/index*", "/myRest/events/**", "/events/**", "/myRest/events", "/events", "/swagger/**", "/kibana/**",
"/elastic/**", "/version/**", "/api-docs/**", "/js/**", "/oauth/uncache_approvals", "/oauth/cache_approvals");
}
}
授权服务器端点需要UserDetailsService
。 在您的OAuth2Config
类中配置用户详细信息服务,如下所示:
@Autowired
private UserDetailsService userDetailsService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore);
endpoints.userDetailsService(userDetailsService);
endpoints.authenticationManager(authenticationManager)
.approvalStoreDisabled();
}
您还可以在WebSecurityConfigurerAdapter
配置它:
@Autowired
private AuthorizationServerEndpointsConfiguration endpoints;
@Override
protected void configure(HttpSecurity http) throws Exception {
if (!endpoints.getEndpointsConfigurer().isUserDetailsServiceOverride()) {
UserDetailsService userDetailsService = http.getSharedObject(UserDetailsService.class);
endpoints.getEndpointsConfigurer().userDetailsService(userDetailsService);
}
// @formatter:off
http
.authorizeRequests()
.antMatchers("/myRest/events/**", "/events/**", "/events", "/myRest/events").permitAll()
.antMatchers("/login.jsp", "/login").permitAll()
.and()
.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")).disable()
.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/myRest/events")).disable()
.sessionManagement().sessionFixation().none();
// @formatter:on
}
如果实现自定义DefaultTokenServices
,我们不需要UserDetailsService
。
@Configuration
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
// ...
.tokenServices(tokenServices(endpoints));
}
public AuthorizationServerTokenServices tokenServices(final AuthorizationServerEndpointsConfigurer endpoints) {
final DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(endpoints.getTokenStore());
tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());
// ...
tokenServices.setAuthenticationManager(
new ProviderManager(List.of(new MyCustomAuthProvider())));
return tokenServices;
}
}
提交消息说:
将 AuthenticationManager 添加到默认令牌服务
以便它可用于检查刷新令牌授予中的用户帐户更改。 如果全局 UserDetailsService 可用,它将用作默认值(例如,如果用户具有 GlobalAuthenticationConfigurer)。 它通过构造 PreAuthenticationAuthenticationProvider 并使用它在 DefaultTokenServices 中对用户进行身份验证来工作。 要自定义该过程,用户可以创建自己的 DefaultTokenServices 并注入 AuthenticationManager。
修复gh-401
添加到@VijayaNandwana 的回答并考虑到@FilipMajernik 的评论,我为OAuthConfig
创建了一个类, OAuthConfig
订单小于扩展WebSecurityConfigurerAdapter
的类。
@Configuration
@Order(1)
public class OAuthConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JdbcTemplate jdbcTemplate;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(jdbcTemplate.getDataSource());
}
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore());
endpoints.userDetailsService(userDetailsService);
endpoints.authenticationManager(authenticationManager)
.approvalStoreDisabled();
}
}
和扩展WebSecurityConfigurerAdapter
类
@Configuration
@EnableWebSecurity
@Order(2)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//Configurations
}
授权端点需要一个 UserDetailsService。
添加这个:
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore());
endpoints.userDetailsService(userDetailsService);
endpoints.authenticationManager(authenticationManager)
.approvalStoreDisabled();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.