title: Upload file from angular to Spring without configuring CORS
body: <p>I'm trying to implement file upload using Angular. Angular is hosted on Apache server with this proxy module configuration:</p>
  
  <pre><code>&lt;Directory /var/www/html/admin&gt;
      Options Indexes FollowSymLinks
      AllowOverride All
      Require all granted
  &lt;/Directory&gt;
  
  &lt;IfModule mod_proxy.c&gt;
      ProxyRequests Off
      ProxyVia Off
      ProxyPreserveHost On
      ProxyStatus On
  
      ProxyPass           /api_admin http://localhost:8080/api_admin
      ProxyPassReverse    /api_admin http://localhost:8080/api_admin
      ProxyPassReverseCookiePath  /api_admin /
  &lt;/IfModule&gt;
  </code></pre>
  
  <p>I use this configuration in order to host the Angular app under sub directory on Apache:</p>
  
  <pre><code>&lt;IfModule mod_rewrite.c&gt;
     RewriteEngine on
     RewriteBase /admin/
     RewriteCond %{REQUEST_FILENAME} -s [OR]
     RewriteCond %{REQUEST_FILENAME} -l [OR]
     RewriteCond %{REQUEST_FILENAME} !-f [OR]
     RewriteCond %{REQUEST_FILENAME} -d
     RewriteRule ^.*$ - [NC,L]
     RewriteRule ^(.*) index.html [NC,L]
  &lt;/IfModule&gt;
  </code></pre>
  
  <p>Typescript code for file upload:</p>
  
  <pre><code>imports (file: any) {
    const url = `http://111.111.111/api_admin/merchants/upload`;
    const formData = new FormData();
    formData.append('file', file, file.name);
    return this.http.post(url, formData);
  }
  </code></pre>
  
  <p>Spring Endpoint:</p>
  
  <pre><code>@RestController
  @RequestMapping("/merchants")
  public class MerchantController {
  
      @PostMapping("/upload")
          public ResponseEntity&lt;String&gt; uploadData(@RequestParam("file") MultipartFile file) throws Exception {
            .........
      }
  }
  </code></pre>
  
  <p>Spring Security configuration:</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
      @Autowired
      private DbUserDetailsService dbuserDetailsService;
  
      @Autowired
      private PasswordEncoder passwordEncoder;
  
      @Override
      @Bean
      public AuthenticationManager authenticationManagerBean() throws Exception {
          return super.authenticationManagerBean();
      }
  
      @Override
      public UserDetailsService userDetailsServiceBean() throws Exception {
          return dbuserDetailsService;
      }
  
      @Override
      protected UserDetailsService userDetailsService() {
          return dbuserDetailsService;
      }
  
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth
                  .userDetailsService(dbuserDetailsService)
                  .passwordEncoder(passwordEncoder);
      }
  
      @Autowired
      public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
          auth.userDetailsService(dbuserDetailsService)
                  .passwordEncoder(passwordEncoder);
      }
  }
  </code></pre>
  
  <p>Paths:</p>
  
  <pre><code>@Configuration
  @EnableResourceServer
  public class ResourceSecurityConfig extends ResourceServerConfigurerAdapter {
  
      @Override
      public void configure(ResourceServerSecurityConfigurer resources) {
          resources.resourceId("resource_id").stateless(true);
      }
  
      @Override
      public void configure(HttpSecurity http) throws Exception {
          http.authorizeRequests()
                  .antMatchers("/users/**").permitAll()
                  .anyRequest().authenticated();
      }
  }
  </code></pre>
  
  <p>But I get CORS error. Usually I can open all pages and make requests to the BE but only this file upload is not working. I tried this:</p>
  
  <pre><code>@CrossOrigin(origins = "*", methods = {RequestMethod.POST, RequestMethod.OPTIONS}, allowedHeaders = {"Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers"}, exposedHeaders = {"Access-Control-Allow-Origin", "Access-Control-Allow-Credentials"})
  @PostMapping("/upload")
              public ResponseEntity&lt;String&gt; uploadData(@RequestParam("file") MultipartFile file) throws Exception {
                .........
          }
  </code></pre>
  
  <p>But again the upload request is blocked by CORS.</p>
  
  <p>Do you know how I can configure Apache mod_rewrite to properly redirect the traffic?</p>
  
  <p>Second way that I tried:</p>
  
  <pre><code>@Configuration
  @EnableResourceServer
  public class ResourceSecurityConfig extends ResourceServerConfigurerAdapter {
  
      @Override
      public void configure(ResourceServerSecurityConfigurer resources) {
          resources.resourceId("resource_id").stateless(true);
      }
  
      @Override
      public void configure(HttpSecurity http) throws Exception {
          http.authorizeRequests()
                  .antMatchers("/users/**").permitAll()
                  .anyRequest().authenticated()
                  .and()
          .cors().disable()
          .authorizeRequests()
          .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
          .anyRequest()
          .fullyAuthenticated()
          .and()
          .httpBasic()
          .and()
          .csrf().disable();
      }
  
      @Bean
      public CorsConfigurationSource corsConfigurationSources() {
          CorsConfiguration configuration = new CorsConfiguration();
          configuration.setAllowedOrigins(Arrays.asList("*"));
          configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
          configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token"));
          configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
          UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
          source.registerCorsConfiguration("/**", configuration);
          return source;
      }
  }
  </code></pre>
  
  <p>With the second configuration I get <code>has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
  auth:1 Failed to load resource: the server responded with a status of 404 (Not Found)</code></p>
  
  <p>What is the best way to achieve this result?</p>
  
  <p>Is there some way to implement this without disabling CORS?</p>