title: Java Spring Security: 401 Unauthorized for token OAuth2 end point
body: <p>I have a fairly basic setup in my Spring Boot project. I'm trying to set up OAuth2 to protect my API but I'm running into issues with my <code>/oauth/token</code> end point. Making either a POST or GET request to my <code>/oauth/token</code> end point results in the following response (With a <code>401 Unauthorized</code> status code):</p>
  
  <pre><code>{
      "timestamp": "2018-09-17T16:46:59.961+0000",
      "status": 401,
      "error": "Unauthorized",
      "message": "Unauthorized",
      "path": "/oauth/token"
  }
  </code></pre>
  
  <p>This is my Authorization server configuration.</p>
  
  <pre><code>import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.beans.factory.annotation.Qualifier;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.security.authentication.AuthenticationManager;
  import org.springframework.security.crypto.password.PasswordEncoder;
  import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
  import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
  import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
  import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
  import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
  import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
  import org.springframework.security.oauth2.provider.token.TokenStore;
  
  @Configuration
  @EnableAuthorizationServer
  public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
      @Autowired
      private TokenStore tokenStore;
  
      @Autowired
      private UserApprovalHandler userApprovalHandler;
  
      @Autowired
      @Qualifier("authenticationManagerBean")
      private AuthenticationManager authenticationManager;
  
      @Autowired
      private PasswordEncoder passwordEncoder;
  
      @Override
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
          clients.inMemory()
                  .withClient("client_id")
                  .secret("secret")
                  .authorizedGrantTypes("password", "authorization_code", "refresh_token")
                  .scopes("read", "write")
                  .accessTokenValiditySeconds(600)
                  .refreshTokenValiditySeconds(3600);
      }
  
      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
          endpoints.tokenStore(this.tokenStore)
                  .userApprovalHandler(this.userApprovalHandler)
                  .authenticationManager(this.authenticationManager);
      }
  
      @Override
      public void configure(AuthorizationServerSecurityConfigurer security) {
          security.tokenKeyAccess("permitAll()")
                  .checkTokenAccess("isAuthenticated()")
                  .passwordEncoder(this.passwordEncoder);
      }
  }
  </code></pre>
  
  <p>This is my resource server configuration. Nothing significant yet:</p>
  
  <pre><code>import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
  import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
  import org.springframework.security.oauth2.provider.token.TokenStore;
  
  public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
      @Autowired
      private TokenStore tokenStore;
  
      @Override
      public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
          resources.tokenStore(this.tokenStore);
      }
  }
  </code></pre>
  
  <p>And finally my standard web security configuration:</p>
  
  <pre><code>import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.security.authentication.AuthenticationManager;
  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  import org.springframework.security.crypto.password.PasswordEncoder;
  import org.springframework.security.oauth2.provider.ClientDetailsService;
  import org.springframework.security.oauth2.provider.approval.ApprovalStore;
  import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
  import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
  import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
  import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
  import org.springframework.security.oauth2.provider.token.TokenStore;
  import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
  
  @Configuration
  @EnableWebSecurity
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
      @Autowired
      private ClientDetailsService clientDetailsService;
  
      @Autowired
      public void globalUserDetails(AuthenticationManagerBuilder builder) throws Exception {
          builder.inMemoryAuthentication()
                  .withUser("user").password("password").roles("ADMIN")
                  .and()
                  .withUser("admin").password("password").roles("USER");
      }
  
      @Override
      protected void configure(HttpSecurity security) throws Exception {
          security.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
      public PasswordEncoder passwordEncoder() {
          return new BCryptPasswordEncoder(8);
      }
  
      @Bean
      @Autowired
      public UserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
          TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
          handler.setTokenStore(tokenStore);
          handler.setRequestFactory(new DefaultOAuth2RequestFactory(this.clientDetailsService));
          handler.setClientDetailsService(this.clientDetailsService);
  
          return handler;
      }
  
      @Bean
      @Autowired
      public ApprovalStore approvalStore(TokenStore tokenStore) {
          TokenApprovalStore store = new TokenApprovalStore();
          store.setTokenStore(tokenStore);
  
          return store;
      }
  }
  </code></pre>
  
  <p>I've messed around quite a bit with different matcher patterns to see if I can get it working but I haven't had any luck. I'm running this in a root context and servlet path on <code>http://localhost:8080</code>.</p>
  
  <p>I can confirm that the end point is mapped in the output when Spring Boot fires up and trying to hit a slightly different end point results in an expected 404.</p>