title: Spring Security OAuth - Access is denied
body: <p>Not sure where I misconfigured AuthorizationServer. The code successfully retrieving use from the db and then for some reason I'm getting this error: <code>Access is denied (user is not anonymous); delegating to AccessDeniedHandler</code>. (see Auth Server log <a href="http://pastebin.com/raw.php?i=R580us0U" rel="nofollow">HERE</a>) Isn't that a whole reason for a user to be logged in to perform the authorization.</p>
  
  <p>Where do I need to specify who can access what?</p>
  
  <p><strong>Authorization Server</strong></p>
  
  <pre><code>@SpringBootApplication
  @ComponentScan(basePackages = {"com.web.authserver"})
  @EntityScan(basePackages = {"com.web.entity", "com.web.authserver"})
  public class HLOAuth2AuthServerApplication {
  
      public static void main(String[] args) {
          SpringApplication.run(HLOAuth2AuthServerApplication.class, args);
      }
  
      @Configuration
      @EnableAuthorizationServer
      protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
  
          @Autowired
          DataSource dataSource;
  
          @Override
          public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
              endpoints
                      .tokenStore(tokenStore())
                      .approvalStore(approvalStore())
                      .authorizationCodeServices(authorizationCodeServices());
          }
  
          @Bean
          public JdbcClientDetailsService clientDetailsService() {
              return new JdbcClientDetailsService(dataSource);
          }
  
          @Bean
          public TokenStore tokenStore() {
              return new JdbcTokenStore(dataSource);
          }
  
          @Bean
          public ApprovalStore approvalStore() {
              return new JdbcApprovalStore(dataSource);
          }
  
          @Bean
          public AuthorizationCodeServices authorizationCodeServices() {
              return new JdbcAuthorizationCodeServices(dataSource);
          }
  
          @Override
          public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
              clients.withClientDetails(clientDetailsService());
          }
  
          @Override
          public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
              oauthServer
  
                      // will be applied to       /oauth/token_key
                      .tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_USER')")
  
                      // will be application to   /oauth/check_token
                      .checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT') || hasAuthority('ROLE_USER') || hasAuthority('USER')")
  
                      .allowFormAuthenticationForClients();
  
          }
      }
  
  
      @Configuration
      protected static class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter {
  
          @Autowired
          private CustomUserDetailsService customUserDetailsService;
  
          @Override
          public void init(AuthenticationManagerBuilder auth) throws Exception {
              // @formatter:off
              auth
                  .userDetailsService(customUserDetailsService)
                  .passwordEncoder(new BCryptPasswordEncoder());
              // @formatter:on
          }
      }
  }
  </code></pre>
  
  <p><strong>Resource Server:</strong></p>
  
  <pre><code>package com.hl.resources.config;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.boot.autoconfigure.security.oauth2.client.*;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.http.HttpMethod;
  import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  import org.springframework.security.config.http.SessionCreationPolicy;
  import org.springframework.security.oauth2.config.annotation.configurers.*;
  import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
  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;
  import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
  
  import javax.sql.DataSource;
  
  
  @Configuration
  @EnableResourceServer
  public class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter{
  
      @Autowired
      DataSource dataSource;
  
      String RESOURCE_ID = "hl_data_resource";
  
      @Override
      public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
          TokenStore tokenStore = new JdbcTokenStore(dataSource);
          resources
                  .resourceId(RESOURCE_ID)
                  .tokenStore(tokenStore);
      }
  
  
  
      @Override
      public void configure(HttpSecurity http) throws Exception {
  
          http.
                  anonymous()
                  .and().requestMatchers().antMatchers("/api/v1/users/user")
                  .and().authorizeRequests().antMatchers("/api/v1/users/user").access("#oauth2.hasScope('read')");
  
          http
                  // For some reason we cant just "permitAll" OPTIONS requests which are needed for CORS support. Spring Security
                  // will respond with an HTTP 401 nonetheless.
                  // So we just put all other requests types under OAuth control and exclude OPTIONS.
                  .authorizeRequests()
                  .antMatchers(HttpMethod.GET, "/**").access("#oauth2.hasScope('read')")
                  .antMatchers(HttpMethod.POST, "/**").access("#oauth2.hasScope('write')")
                  .antMatchers(HttpMethod.PATCH, "/**").access("#oauth2.hasScope('write')")
                  .antMatchers(HttpMethod.PUT, "/**").access("#oauth2.hasScope('write')")
                  .antMatchers(HttpMethod.DELETE, "/**").access("#oauth2.hasScope('write')")
                  .and()
  
                  // Add headers required for CORS requests.
                  .headers().addHeaderWriter((request, response) -&gt; {
              response.addHeader("Access-Control-Allow-Origin", "*");
  
              if (request.getMethod().equals("OPTIONS")) {
                  response.setHeader("Access-Control-Allow-Methods", request.getHeader("Access-Control-Request-Method"));
                  response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
              }
          });
  
          http.authorizeRequests().antMatchers(HttpMethod.POST, "/v1/files/**").permitAll();
          // @formatter:off
  //         http
  //         .requestMatchers().antMatchers("/bookmarks", "/bookmarks/**")
  //         .and()
  //         .authorizeRequests().anyRequest().access("#oauth2.hasScope('write')");
           // @formatter:on
  
      }
  
  }
  </code></pre>
  
  <p><strong>Web Client App</strong></p>
  
  <pre><code>@SpringBootApplication
  @EnableZuulProxy
  @EnableOAuth2Sso
  @EnableConfigurationProperties
  public class HLOAuth2TestWebClientApplication {
  
      public static void main(String[] args) {
          SpringApplication.run(HLOAuth2TestWebClientApplication.class, args);
      }
  
      @Configuration
      @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
      protected static class SecurityConfiguration extends OAuth2SsoConfigurerAdapter {
  
          @Autowired
          OAuth2SsoProperties oAuth2SsoProperties;
  
          @Override
          public void match(RequestMatchers matchers) {
              matchers.anyRequest();
          }
  
          @Override
          public void configure(HttpSecurity http) throws Exception {
              http
                      .authorizeRequests()
                      .antMatchers("/index.html", "/home.html" ,"/login").permitAll()
  
                      .anyRequest().authenticated()
  
                      .and().csrf().csrfTokenRepository(csrfTokenRepository())
                      .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
              //.and().csrf().disable()
              ;
          }
  
          private Filter csrfHeaderFilter() {
              return new OncePerRequestFilter() {
                  @Override
                  protected void doFilterInternal(HttpServletRequest request,
                                                  HttpServletResponse response, FilterChain filterChain)
                          throws ServletException, IOException {
                      CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
                              .getName());
                      if (csrf != null) {
                          Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                          String token = csrf.getToken();
                          if (cookie == null || token != null
                                  &amp;&amp; !token.equals(cookie.getValue())) {
                              cookie = new Cookie("XSRF-TOKEN", token);
                              cookie.setPath("/");
                              response.addCookie(cookie);
                          }
                      }
                      filterChain.doFilter(request, response);
                  }
              };
          }
  
  
          private CsrfTokenRepository csrfTokenRepository() {
              HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
              repository.setHeaderName("X-XSRF-TOKEN");
              return repository;
          }
      }
  }
  </code></pre>
  
  <p>Web Client application.properties file:</p>
  
  <pre><code>server.port=7070
  server.context-path=
  server.tomcat.basedir=target/tomcat
  vaadin.servlet.url-mapping=/ui
  security.basic.enabled=false
  debug=true
  logging.level.org.springframework.security=DEBUG
  
  #spring.oauth2.sso.home.secure=false
  #spring.oauth2.sso.home.path=/,/**/*.html
  spring.oauth2.client.accessTokenUri = http://localhost:9090/a/oauth/token
  spring.oauth2.client.userAuthorizationUri = http://localhost:9090/a/oauth/authorize
  spring.oauth2.client.clientId = acme
  spring.oauth2.client.id=testWebClient
  spring.oauth2.client.clientSecret = acmesecret
  spring.oauth2.client.scope[0]=openid
  spring.oauth2.client.scope[1]=read
  #spring.oauth2.client.grant-type=implicit
  spring.oauth2.client.clientAuthenticationScheme = form
  
  spring.oauth2.resource.userInfoUri = http://localhost:8080/api/v1/users/user
  
  zuul.routes.resource.path = /resource/**
  zuul.routes.resource.url = http://localhost:7070
  zuul.routes.user.path = /user/**
  zuul.routes.user.url = http://localhost:9090/a/v1/users/user
  </code></pre>
  
  <p>Web Client Server Log:</p>
  
  <p><a href="http://pastebin.com/raw.php?i=vi2wEzSA" rel="nofollow">http://pastebin.com/raw.php?i=vi2wEzSA</a></p>
  
  <p>Authorization Server Log:</p>
  
  <p><a href="http://pastebin.com/raw.php?i=R580us0U" rel="nofollow">http://pastebin.com/raw.php?i=R580us0U</a></p>