繁体   English   中英

使用 spring security 和 oauth2 刷新令牌调用失败,错误:需要 UserDetailsS​​ervice

[英]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。

由于某种原因, DefaultTokenServiceAuthenticationManager不是空的,它尝试验证用户以检查他是否仍然存在。 我认为它被初始化是因为一些 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 添加到默认令牌服务

以便它可用于检查刷新令牌授予中的用户帐户更改。 如果全局 UserDetailsS​​ervice 可用,它将用作默认值(例如,如果用户具有 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
}

授权端点需要一个 UserDetailsS​​ervice。

添加这个:

@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM