Reputation: 121
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
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
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