title: Cross Domain Ajax Request to Spring MVC Controller fails with 302 error
body: <p>For a Proof of concept I am trying to load a jsp from one spring boot app on a section of a page on another.</p>
  
  <p>I am using JQuery to make a $.ajax() request but from what I can see is that the request isnt even getting to spring filters or controller. The controller response normally when sending from its own browser window.</p>
  
  <p>Error: 
  Failed to load <a href="http://localhost:8082/settings2" rel="nofollow noreferrer">http://localhost:8082/settings2</a>: Redirect from '<a href="http://localhost:8082/settings2" rel="nofollow noreferrer">http://localhost:8082/settings2</a>' to '<a href="http://localhost:8082/settings2/" rel="nofollow noreferrer">http://localhost:8082/settings2/</a>' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '<a href="http://localhost:8080" rel="nofollow noreferrer">http://localhost:8080</a>' is therefore not allowed access.</p>
  
  <p>2 Applications: settings &amp; settings2. Settings one is trying make an AJAX request to a controller on settings2</p>
  
  <p>settings app page (trying to talk to settings2 app)
      </p>
  
  <pre><code>&lt;script&gt;
  $.ajax({url:'http://localhost:8082/settings2',
      type:"POST");
  }});
  //No success method because chrome console already showing error
  &lt;/script&gt;
  &lt;/body&gt;
  </code></pre>
  
  <p>Settings2 configuration app (WebMvcConfigurerAdapter is flagged as depreciated)
      @Configuration
      public class WebConfig extends WebMvcConfigurerAdapter {</p>
  
  <pre><code>@Override
  public void addCorsMappings(CorsRegistry registry) {
      registry.addMapping("/").allowedOrigins("http://localhost:8080", "*")
              .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS").allowedHeaders("*")
              .exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Methods",
                      "Access-Control-Allow-Headers", "Access-Control-Max-Age", "Access-Control-Request-Headers",
                      "Access-Control-Request-Method");
  }
  
  }
  </code></pre>
  
  <p>Settings2 websecurity config</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
  
      http.cors();
  }
  
  @Bean
  public CorsConfigurationSource corsConfigurationSource() {
      final CorsConfiguration configuration = new CorsConfiguration();
      configuration.setAllowedOrigins(Arrays.asList("*"));
      configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
      configuration.setExposedHeaders(Arrays.asList("Access-Control-Allow-Origin", "Access-Control-Allow-Methods",
              "Access-Control-Allow-Headers", "Access-Control-Max-Age", "Access-Control-Request-Headers",
              "Access-Control-Request-Method"));
      // setAllowCredentials(true) is important, otherwise:
      // The value of the 'Access-Control-Allow-Origin' header in the response must
      // not be the wildcard '*' when the request's credentials mode is 'include'.
      configuration.setAllowCredentials(true);
      // setAllowedHeaders is important! Without it, OPTIONS preflight request
      // will fail with 403 Invalid CORS request
      configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
      final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
      source.registerCorsConfiguration("/", configuration);
      return source;
  }
  }
  </code></pre>
  
  <p>settings2 app Cors Filter</p>
  
  <pre><code>public class WebSecurityCorsFilter implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
  }
  
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          throws IOException, ServletException {
      HttpServletResponse res = (HttpServletResponse) response;
      res.setHeader("Access-Control-Allow-Origin", "*");
      res.setHeader("Access-Control-Allow-Methods", "*");
      res.setHeader("Access-Control-Max-Age", "3600");
      res.setHeader("Access-Control-Allow-Headers", "x-requested-with");
      chain.doFilter(request, res);
  }
  
  @Override
  public void destroy() {
  }
  }
  </code></pre>
  
  <p>Settings2 controller
      @CrossOrigin
      @RestController
      public class SettingsController {</p>
  
  <pre><code>@CrossOrigin
  @RequestMapping(value = "/", method = { RequestMethod.POST })
  public String getPagePost(HttpServletResponse response) {
  
      return "home";
  }
  
  @RequestMapping(value = "/", method = RequestMethod.OPTIONS)
  public ResponseEntity handle() {
      return new ResponseEntity(HttpStatus.OK);
  }
   }
  </code></pre>
  
  <p>Settings2 pom</p>
  
  <pre><code> &lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
  &lt;groupId&gt;com.ddavey&lt;/groupId&gt;
  &lt;artifactId&gt;settings&lt;/artifactId&gt;
  &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
  &lt;packaging&gt;war&lt;/packaging&gt;
  
  &lt;name&gt;settings2&lt;/name&gt;
  &lt;description&gt;Development Team Register Application&lt;/description&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;2.0.0.RELEASE&lt;/version&gt;
  &lt;/parent&gt;
  
  &lt;properties&gt;
      &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
      &lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;
      &lt;java.version&gt;1.8&lt;/java.version&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-web&lt;/artifactId&gt;
      &lt;/dependency&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.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
          &lt;optional&gt;true&lt;/optional&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;jstl&lt;/groupId&gt;
          &lt;artifactId&gt;jstl&lt;/artifactId&gt;
          &lt;version&gt;1.2&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
          &lt;scope&gt;provided&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.apache.tomcat.embed&lt;/groupId&gt;
          &lt;artifactId&gt;tomcat-embed-jasper&lt;/artifactId&gt;
          &lt;scope&gt;provided&lt;/scope&gt;
      &lt;/dependency&gt;
  &lt;/dependencies&gt;
  
  &lt;build&gt;
      &lt;plugins&gt;
          &lt;plugin&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
          &lt;/plugin&gt;
      &lt;/plugins&gt;
  &lt;/build&gt;
  
  
  &lt;/project&gt;
  </code></pre>
  
  <p>Settings2 app startup logs (Nothing further logged even when the request is sent):</p>
  
  <p>.   ____          _            __ _ _
   /\ / <strong><em>'</em> __ _ <em>(</em>)_ __  __ _ \ \ \ \
  ( ( )_</strong> | '_ | '<em>| | '</em> / <em>` | \ \ \ \
   \/  <strong></em>)| |<em>)| | | | | || (</em>| |  ) ) ) )
    '  |____| .</strong>|<em>| |</em>|<em>| |</em>__, | / / / /
   =========|_|==============|___/=/<em>/</em>/_/
   :: Spring Boot ::        (v2.0.0.RELEASE)</p>
  
  <p>2018-03-15 13:04:07,585 2029 [restartedMain] DEBUG o.s.s.c.a.a.c.AuthenticationConfiguration$EnableGlobalAuthenticationAutowiredConfigurer - Eagerly initializing {webSecurityConfig=com.ddavey.settings.WebSecurityConfig$$EnhancerBySpringCGLIB$$5891dd83@30260b10}
  2018-03-15 13:04:07,724 2168 [restartedMain] INFO  o.s.s.w.DefaultSecurityFilterChain - Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher@1, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@52e26e68, org.springframework.security.web.context.SecurityContextPersistenceFilter@624ab72f, org.springframework.security.web.header.HeaderWriterFilter@618df83a, org.springframework.web.filter.CorsFilter@1f0c50a, org.springframework.security.web.csrf.CsrfFilter@174cc9cb, org.springframework.security.web.authentication.logout.LogoutFilter@4fddc7f, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@23710a6c, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@231f9098, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@72fafc4, org.springframework.security.web.session.SessionManagementFilter@17b054e5, org.springframework.security.web.access.ExceptionTranslationFilter@57cd8b95]</p>