首页 文章

Spring Boot Oauth2刷新令牌 - IllegalStateException

提问于
浏览
0

因此,我可以使用标准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 回答

  • 0

    在这里找到答案: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)功能 .

    @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());
        }
    
    }
    

    正如解决方案的作者评论“全局认证配置在Spring Boot中命令之后(因此这里的设置覆盖了Boot中的设置)” . 虽然他也提到这不会是 Spring 季启动1.2.3中的问题,但是现在这就是我需要让它工作并找到我的UserDetailsService .

  • 0

    在AuthorizationServerConfig类中:

    @Autowired
    private CustomUserDetailsService userDetailsService;
    
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
            .authenticationManager(authenticationManager)
            .tokenStore(tokenStore())
            .userDetailsService(userDetailsService);
    }
    
  • 0

    我正在使用Spring boot OAuth2,并遇到同样的异常
    IllegalStateException - UserDetailsService Required .

    我正在使用内存身份验证管理器进行测试 . 我解决了如下

    • WebSecurityConfig(扩展WebSecurityConfigurerAdapter) - declear默认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
    
    }
    

相关问题