title: Spring security OAuth2 Refresh Token - IllegalStateException, UserDetailsService is required
body: <p>I am new to Spring security and developing spring REST API with OAuth2 authentication and authorization. Everything is working fine, but when I request Refresh token, than I get error which states -</p>
  
  <blockquote>
    <p>org.springframework.security.oauth2.provider.endpoint.TokenEndpoint handleException
    IllegalStateException, UserDetailsService is required.</p>
  </blockquote>
  
  <p><strong>NOTE:</strong> I am using custom authentication provider to authenticate user credentials from database.</p>
  
  <p>Here is my code:</p>
  
  <p><strong>Web security configure adapter:</strong></p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
  
  @Autowired
  private ClientDetailsService clientDetailsService;
  
  @Autowired
  private CustomAuthenticationProvider authProvider;
  
  @Override
  protected void configure(
    AuthenticationManagerBuilder auth) throws Exception {
      auth.authenticationProvider(authProvider);
  }
  
  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http
      .csrf().disable()
      .anonymous().disable()
      .authorizeRequests()
      .antMatchers("/oauth/token").permitAll();
  }
  
  @Override
  @Bean
  public AuthenticationManager authenticationManagerBean() throws Exception {
      return super.authenticationManagerBean();
  }
  
  
  @Bean
  public TokenStore tokenStore() {
      return new InMemoryTokenStore();
  }
  
  @Bean
  @Autowired
  public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
      TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
      handler.setTokenStore(tokenStore);
      handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
      handler.setClientDetailsService(clientDetailsService);
      return handler;
  }
  
  @Bean
  @Autowired
  public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
      TokenApprovalStore store = new TokenApprovalStore();
      store.setTokenStore(tokenStore);
      return store;
  }
  
  }
  </code></pre>
  
  <p><strong>Custom Authentication Provider</strong></p>
  
  <pre><code>@Component
  public class CustomAuthenticationProvider implements AuthenticationProvider {
  
  @Override
  public Authentication authenticate(Authentication authentication) 
    throws AuthenticationException {
  
      String username = authentication.getName();
      String password = authentication.getCredentials().toString();
      Ss_admin_service ss_admin_service = new Ss_admin_service();
      Ss_admin ss_admin = new Ss_admin();
      ss_admin.setA_password(password);
      ss_admin.setA_username(username);
      ss_admin_service.doLogin(ss_admin);
      if(!ss_admin_service.doLogin(ss_admin)) {
          throw new BadCredentialsException("Invalid username/password");
      }
      return new UsernamePasswordAuthenticationToken(username, password, (Collection&lt;? extends GrantedAuthority&gt;) new ArrayList&lt;&gt;());
  }
  
  @Override
  public boolean supports(Class&lt;?&gt; authentication) {
      return authentication.equals(UsernamePasswordAuthenticationToken.class);
  }
  
  }
  </code></pre>
  
  <p><strong>Authorization Server Configuration</strong></p>
  
  <pre><code>@Configuration
  @EnableAuthorizationServer
  public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
  
  private static String REALM="MY_OAUTH_REALM";
  
  @Autowired
  private TokenStore tokenStore;
  
  @Autowired
  private UserApprovalHandler userApprovalHandler;
  
  @Autowired
  @Qualifier("authenticationManagerBean")
  private AuthenticationManager authenticationManager;
  
  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  
      clients.inMemory()
          .withClient("my-trusted-client")
          .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
          .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
          .scopes("read", "write", "trust")
          .secret("secret")
          .accessTokenValiditySeconds(10).//Access token is only valid for 10 sec for testing.
          refreshTokenValiditySeconds(10);//Refresh token is only valid for 10 sec for testing.
  }
  
  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
      endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
              .authenticationManager(authenticationManager);
  }
  
  @Override
  public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
      oauthServer.realm(REALM+"/client");
  }
  
  }
  </code></pre>
  
  <p><strong>Resource server config</strong></p>
  
  <pre><code>@Configuration
  @EnableResourceServer
  public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
  
  private static final String RESOURCE_ID = "SPRING_REST_API";
  
  @Override
  public void configure(ResourceServerSecurityConfigurer resources) {
      resources.resourceId(RESOURCE_ID).stateless(false);
  }
  
  @Override
  public void configure(HttpSecurity http) throws Exception {
      http
      .anonymous().disable()
      .requestMatchers().antMatchers("/admin/**")
      .and().authorizeRequests()
      .antMatchers("/admin/**").access("hasRole('ADMIN')")
      .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
  }
  
  }
  </code></pre>