title: SpringBoot 1.5.x + Security + OAuth2
body: <p>I have a Spring Boot REST API with OAuth2 Security. </p>
  
  <p>Today I have upgraded my version of <code>spring-boot-starter-parent</code> from <code>1.4.2</code> to <code>1.5.2</code>.</p>
  
  <p>Changes completely confused me. </p>
  
  <p>Before, I could test my REST API with Postman. When my access token was incorrect or I didnt have a rights for specific resources, server response was like:</p>
  
  <pre><code>{
    "error": "access_denied",
    "error_description": "Access is denied"
  }
  </code></pre>
  
  <p>Now it keeps redirect me to <code>/login</code> page... When I log in - it show my resource without any OAuth2 authentication...</p>
  
  <p>I have tried to disable it and I found this magic property:</p>
  
  <pre><code>security.oauth2.resource.filter-order = 3
  </code></pre>
  
  <p>This line turned off redirects to login page.</p>
  
  <p>However, my questions are:</p>
  
  <ul>
  <li>what happened between these 2 releases in term of security?</li>
  <li>is this "strange" line is an only valid fix?</li>
  <li>what is a purpose of this login page and what authentication it is using (I checked a requests and responses in Google Chrome and I can't see any access tokens and oauth2 stuff so it is using user repository then only?)</li>
  </ul>
  
  <p>Some more important parts of my code:</p>
  
  <p><strong>pom.xml</strong></p>
  
  <pre><code>&lt;!--- .... --&gt;
  &lt;parent&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
      &lt;version&gt;1.5.2.RELEASE&lt;/version&gt;
  &lt;/parent&gt;
  &lt;properties&gt;
      &lt;!--- .... --&gt;
      &lt;spring-security-oauth.version&gt;2.1.0.RELEASE&lt;/spring-security-oauth.version&gt;
      &lt;!--- .... --&gt;
  &lt;/properties&gt;
  &lt;dependencies&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
      &lt;/dependency&gt;
      &lt;!-- Monitor features --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-actuator&lt;/artifactId&gt;
      &lt;/dependency&gt;
      &lt;!-- Security + OAuth2 --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.security.oauth&lt;/groupId&gt;
          &lt;artifactId&gt;spring-security-oauth2&lt;/artifactId&gt;
          &lt;version&gt;${spring-security-oauth.version}&lt;/version&gt;
      &lt;/dependency&gt;
  &lt;!--- .... --&gt;
  </code></pre>
  
  <p><strong>application.properties</strong></p>
  
  <pre><code>#other properties
  security.oauth2.resource.filter-order = 3
  </code></pre>
  
  <p><strong>OAuth2.java</strong></p>
  
  <pre><code>public class OAuth2 {
  @EnableAuthorizationServer
  @Configuration
  @ComponentScan
  public static class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
  
      @Autowired
      private AuthenticationManager authenticationManagerBean;
      @Autowired
      private UserDetailsService userDetailsService;
  
      @Override
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
          clients.inMemory()
                  .withClient("trusted_client")
                  .authorizedGrantTypes("password", "refresh_token")
                  .scopes("read", "write");
      }
  
      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
          endpoints.authenticationManager(authenticationManagerBean).userDetailsService(userDetailsService);
      }
  
      @Override
      public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
          security.allowFormAuthenticationForClients();
      }
  }
  
  @EnableResourceServer
  @Configuration
  @ComponentScan
  public static class ResourceServer extends ResourceServerConfigurerAdapter {
  
      @Autowired
      private RoleHierarchy roleHierarchy;
  
      private SecurityExpressionHandler&lt;FilterInvocation&gt; webExpressionHandler() {
          DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
          defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy);
          return defaultWebSecurityExpressionHandler;
      }
  
      @Override
      public void configure(HttpSecurity http) throws Exception {
          http
                  .authorizeRequests().expressionHandler(webExpressionHandler())
                  .antMatchers("/api/**").hasRole("DEVELOPER");
      }
  }
  }
  </code></pre>
  
  <p><strong>Security.java</strong></p>
  
  <pre><code>@EnableWebSecurity
  @Configuration
  @ComponentScan
  public class Security extends WebSecurityConfigurerAdapter {
  
  @Autowired
  private UserDetailsService userDetailsService;
  
  @Bean
  public JpaAccountDetailsService userDetailsService(AccountsRepository accountsRepository) {
      return new JpaAccountDetailsService(accountsRepository);
  }
  
  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
  }
  
  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
      return super.authenticationManagerBean();
  }
  
  @Bean
  public PasswordEncoder passwordEncoder(){
      return new BCryptPasswordEncoder();
  }
  }
  </code></pre>