title: Spring Boot, Security and OAuth2 - mobile app backend
body: <p>I am trying to protect my rest service which is a backend to my Android and iOS application. I want protect all endpoints on this service to allow to communicate only with my mobile application.</p>
  
  <p>I figure out this flow (i am not sure if it is correct):</p>
  
  <ol>
  <li>Secure all endpoints by Basic Authentication header with client_id:client secret (standard way - in authorization header, base64 format). Those endpoints will be for not logged in users.</li>
  <li>Secure part of the endpoints using OAuth2. Those endpoints will be for logged in users.</li>
  </ol>
  
  <p>Unfortunatelly i do not know how to apply that flow. I created confguration mentioned bellow but its not working as i expected.</p>
  
  <p>So, two questions:</p>
  
  <ol>
  <li>Is this flow correct and possible with spring security and oauth?</li>
  <li>How to apply this flow in my configuration.</li>
  </ol>
  
  <p>Security config:</p>
  
  <pre><code>@Order(1)
  @Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
      private String securityRealm = "MyRealm";
  
      @Autowired
      private UserDetailsService userDetailsService;
  
      @Autowired
      private PasswordEncoder passwordEncoder;
  
      @Bean
      @Override
      protected AuthenticationManager authenticationManager() throws Exception {
          return super.authenticationManager();
      }
  
      @Bean
      public PasswordEncoder passwordEncoder() {
          return new BCryptPasswordEncoder();
      }
  
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth
          .userDetailsService(userDetailsService)
          .passwordEncoder(passwordEncoder);
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
              .sessionManagement()
              .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
              .and()
              .authorizeRequests()
              .antMatchers("/user").authenticated()
              .and()
              .httpBasic().realmName(securityRealm)
              .and()
              .csrf().disable();
      }
  }
  </code></pre>
  
  <p>Authorization config:</p>
  
  <pre><code>@Configuration
  @EnableAuthorizationServer
  public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
  
      private final String clientId = "clientid";
      private final String clientSecret = "clientsecret";
      private final String grantType = "password";
      private final String scopeRead = "read";
      private final String scopeWrite = "write";
      private final String resourceIds = "resourcesId";
  
      @Autowired
      DataSource dataSource;
  
      @Autowired
      private AuthenticationManager authenticationManager;
  
      @Override
      public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
          configurer
              .inMemory()
              .withClient(clientId).secret(clientSecret)
              .authorizedGrantTypes(grantType, "refresh_token", "client_credential")
              .scopes(scopeRead, scopeWrite)
              .resourceIds(resourceIds);
      }
  
      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
          endpoints
              .tokenStore(tokenStore())
              .authenticationManager(authenticationManager)
              .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
      }
  
      @Bean
      public TokenStore tokenStore(){
          return new JdbcTokenStore(dataSource);
      }
  }
  </code></pre>
  
  <p>And Resources server:</p>
  
  <pre><code>@Order(2)
  @Configuration
  @EnableResourceServer
  public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
  
      private final String resourceIds = "resourcesId";
  
      @Override
      public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
          resources
              .resourceId(resourceIds);
      }
  
      @Override
      public void configure(HttpSecurity http) throws Exception {
          http
              .requestMatchers()
              .and()
              .authorizeRequests()
              .antMatchers("/places").authenticated()
              .antMatchers("/places/**").authenticated()
              .antMatchers("/welcome").permitAll()
              .antMatchers("/welcome/**").permitAll();
      }
  }
  </code></pre>