Patheek Chokshi
Patheek Chokshi

Reputation: 121

CORS for spring boot not in response header

I tried implementing the GLOBAL CORS as suggested by this spring site for my spring boot Applications which gets deployed to Pivotal Cloud Foundry.

https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/cors.html

However, when I send OPTIONS message to the service end point, The response does not return any CORS headers in it. So, application fails to make POST call after preflight. Here is my implementation.

@Configuration
@EnableWebMvc
public class CORSConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {

        registry.addMapping("*/**")
            .allowedOrigins("*")
            .allowedMethods("GET", "POST", "OPTIONS")
            .allowedHeaders("Content-Type", "Authorization")
            .allowCredentials(false).maxAge(3600);
    }
}

Am i missing anything ?

Upvotes: 2

Views: 7691

Answers (2)

Aditya lahiri
Aditya lahiri

Reputation: 65

As of Spring Boot 3.3, you need to do the following to configure CORS for your app.

Add CORS config in the SecurityFilterChain:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) {
    http.cors(Customizer.withDefaults()); //or however else you would like to configure CORS
    //other settings
    return http.build();
}

Create a Bean named corsFilter:

@Bean
public CorsFilter corsFilter() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOriginPatterns(List.of("https://*.example.net"));
    configuration.setAllowedHeaders(List.of("Origin", "Content-Type", "Accept", "responseType", "Authorization"));
    configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "OPTIONS", "DELETE"));
    configuration.setMaxAge(3600L);
    configuration.setAllowCredentials(true);
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return new CorsFilter(source);
}

Above is an example configuration. Please configure according to your desired settings.

The relevant headers will be added to the response of valid PreFlight (OPTIONS) requests.

Upvotes: 1

Patheek Chokshi
Patheek Chokshi

Reputation: 121

Ok. I found where the problem was. HTTP OPTIONS request alone does not constitute the pre-flight request. In order for OPTIONS to be considered pre-flight request, it needs 2 more request headers. one is Origin, which I added to the request. However, what i missed was on the Access-Control-Request-Method. Pre-flight request generated by browsers would have all 3 http request headers in it. Once i added all 3 request headers, I saw my CORS headers coming back in the response.

Here is the sample code and response.

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableWebMvc
public class CORSConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("*")
            .allowedMethods("POST")
            .allowedHeaders("Content-Type", "Authorization")
            .allowCredentials(false)
            .maxAge(32400);  // 9 hours max age
    }
}

Here is the request :

OPTIONS /my-end-point HTTP/1.1
Host: my-app.my-domain.com
Origin: http://localhost:8090
Access-Control-Request-Method: POST
Cache-Control: no-cache
Postman-Token: bc7171bc-7f84-3b44-a304-818627411a72
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

Here is the response.

access-control-allow-methods →POST
access-control-allow-origin →*
access-control-max-age →32400

Upvotes: 6

Related Questions