title: Spring Boot and OAuth2 CORS
body: <p>when we access the apis from a node server using axios client it always run in to the following error:</p>
  
  <pre><code>XMLHttpRequest cannot load http://localhost:8089/public/api. Redirect from 'http://localhost:8089/public/api/' to 'http://localhost:8089/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3002' is therefore not allowed access.
  </code></pre>
  
  <p>My configuration as follows:</p>
  
  <pre><code>import java.security.Principal;
  import java.util.ArrayList;
  import java.util.LinkedHashMap;
  import java.util.List;
  import java.util.Map;
  
  import javax.servlet.Filter;
  
  import org.apache.catalina.filters.CorsFilter;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.boot.SpringApplication;
  import org.springframework.boot.autoconfigure.SpringBootApplication;
  import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
  import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices;
  import org.springframework.boot.context.properties.ConfigurationProperties;
  import org.springframework.boot.context.properties.NestedConfigurationProperty;
  import org.springframework.boot.web.servlet.FilterRegistrationBean;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.core.annotation.Order;
  import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  import org.springframework.security.oauth2.client.OAuth2ClientContext;
  import org.springframework.security.oauth2.client.OAuth2RestTemplate;
  import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter;
  import org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter;
  import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
  import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
  import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
  import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
  import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
  import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
  import org.springframework.security.web.access.channel.ChannelProcessingFilter;
  import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
  import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
  import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.RestController;
  import org.springframework.web.cors.CorsUtils;
  import org.springframework.web.filter.CompositeFilter;
  
  @SpringBootApplication
  @EnableOAuth2Client
  @EnableAuthorizationServer
  @Order(6)
  public class MonitoringApiApplication extends WebSecurityConfigurerAdapter {
  
      @Autowired
      OAuth2ClientContext oauth2ClientContext;
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          // @formatter:off
          http
                  .antMatcher("/**").authorizeRequests().antMatchers("/","/user**", "/login**", "/webjars/**").permitAll().anyRequest()
  
                  .authenticated().and().exceptionHandling()
                  .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/")).and().logout()
                  .logoutSuccessUrl("/").permitAll().and().csrf().disable()
                  .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
  
          // @formatter:on
      }
  
      @Configuration
      @EnableResourceServer
      protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
          @Override
          public void configure(HttpSecurity http) throws Exception {
              // @formatter:off
              http.antMatcher("/me").authorizeRequests().anyRequest().authenticated();
              // @formatter:on
          }
      }
  
      public static void main(String[] args) {
  
          SpringApplication.run(MonitoringApiApplication.class, args);
      }
  
      @Bean
      public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
          FilterRegistrationBean registration = new FilterRegistrationBean();
          registration.setFilter(filter);
          registration.setOrder(-100);
          return registration;
      }
  
      @Bean
      @ConfigurationProperties("github")
      public ClientResources github() {
          return new ClientResources();
      }
  
      @Bean
      @ConfigurationProperties("facebook")
      public ClientResources facebook() {
          return new ClientResources();
      }
  
      private Filter ssoFilter() {
          CompositeFilter filter = new CompositeFilter();
          List&lt;Filter&gt; filters = new ArrayList&lt;&gt;();
          filters.add(ssoFilter(facebook(), "/login/facebook"));
          filters.add(ssoFilter(github(), "/login/github"));
          filter.setFilters(filters);
          return filter;
      }
  
      private Filter ssoFilter(ClientResources client, String path) {
          OAuth2ClientAuthenticationProcessingFilter oAuth2ClientAuthenticationFilter = new OAuth2ClientAuthenticationProcessingFilter(
                  path);
          OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext);
          oAuth2ClientAuthenticationFilter.setRestTemplate(oAuth2RestTemplate);
          UserInfoTokenServices tokenServices = new UserInfoTokenServices(client.getResource().getUserInfoUri(),
                  client.getClient().getClientId());
          tokenServices.setRestTemplate(oAuth2RestTemplate);
          oAuth2ClientAuthenticationFilter.setTokenServices(tokenServices);
          return oAuth2ClientAuthenticationFilter;
      }
  
  }
  
  class ClientResources {
  
      @NestedConfigurationProperty
      private AuthorizationCodeResourceDetails client = new AuthorizationCodeResourceDetails();
  
      @NestedConfigurationProperty
      private ResourceServerProperties resource = new ResourceServerProperties();
  
      public AuthorizationCodeResourceDetails getClient() {
          return client;
      }
  
      public ResourceServerProperties getResource() {
          return resource;
      }
  }
  </code></pre>
  
  <p>Filter configuration:</p>
  
  <pre><code>@Bean
  public FilterRegistrationBean  corsFilter() {
      UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
      CorsConfiguration config = new CorsConfiguration();
      config.setAllowCredentials(true);
      config.addAllowedOrigin("http://localhost:3002");
      config.addAllowedHeader("*");
      config.addAllowedMethod("*");
      source.registerCorsConfiguration("/**", config);
      FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
      bean.setOrder(0);
      return bean;
  }
  </code></pre>
  
  <p>spring boot version:</p>
  
  <pre><code>&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.4.0.RELEASE&lt;/version&gt;
      &lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt;
  &lt;/parent&gt;
  </code></pre>
  
  <p>if i add /public/** to antMatchers it works ,which means the enpoints are not protected by the ssoFilter() , i have tried credentials to false origin to *  but none of the worked </p>