Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global CORS configuration breaks when migrating to Spring Boot 2.0.x

Why is my 'Access-Control-Allow-Credentials' no longer being sent in response to preflight calls (OPTIONS) under Spring Boot 2.0.x (2.0.1.RELEASE in my case)? Here is my Global CORS Configuration that works fine under Spring Boot 1.5.6:

@Configuration
public class CorsConfig {

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins(
                        "http://localhost:3000",..)
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD");
        }
    };
}}

My pom dependencies (I am doing my own security and avoiding Spring Security):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

My service call to the REST endpoints fails the preflight:

Failed to load http://localhost:8080/api/v5/sec/auth: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://localhost:3000' is therefore not allowed access.

I have verified that 'Access-Control-Allow-Credentials' header is indeed present in the case of Spring Boot 1.5.6 and missing under Spring Boot 2.0.1.

All the documentation I can find, including the latest on spring.io here, says my global configuration is still correct, even though WebMvcConfigurerAdapter appears to be deprecated now.


UPDATE:


Here are the response headers before and after the migrate:

Before Migrate (Spring Boot 1.5.6):

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:3000
Content-Type: application/json;charset=UTF-8
Date: Day, dd Mon yyyy hh:mm:ss GMT
Transfer-Encoding: chunked
Vary: Origin

After Migrate (Spring Boot 2.0.1 - Access-Control-Allow-Credentials header missing, but others changed/added):

Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: GET,HEAD,POST <-- My specified methods ignored
Access-Control-Allow-Origin: * <-- My specified origin ignored
Access-Control-Max-Age: 1800
Content-Length: 0
Date: Day, dd Mon yyyy hh:mm:ss GMT
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers

like image 491
Geyser14 Avatar asked May 05 '18 00:05

Geyser14


People also ask

Is CORS enabled by default in Spring boot?

No. You need to add @CrossOrigin annotation by yourself to get CORS Support in Spring. Enabling CORS (Cross-origin resource sharing) by default will be a serious security issue.

How do Spring boots handle CORS?

To code to set the CORS configuration globally in main Spring Boot application is given below. Now, you can create a Spring Boot web application that runs on 8080 port and your RESTful web service application that can run on the 9090 port.

How do you turn on CORS at Spring security level?

To enable CORS support through Spring security, configure CorsConfigurationSource bean and use HttpSecurity. cors() configuration. @LahiruGamage it doesn't matter, it's a Spring bean like any others, so as long as it's within a (sub)package relative to the main class, it will work.


2 Answers

This was missing from the Spring doc and many examples but the answer was very easy. I just saw the allowCredentials() method on CorsRegistry and added .allowCredentials(true) to the registry method chain and that added the Access-Control-Allow-Credentials header back in.

Also, I no longer use the deprecated WebMvcConfigurerAdapter, but now implement WebMvcConfigurer and override the addCorsMappings() method.

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {

        registry.addMapping("/**")
                .allowedOrigins(
                        "http://localhost:3000",..)
                .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
                .allowCredentials(true)
        ;
    }
    
}
like image 131
Geyser14 Avatar answered Nov 12 '22 16:11

Geyser14


If you are using Spring Boot 2.0.x

CORS support is disabled by default and is only enabled once the management.endpoints.web.cors.allowed-origins property has been set. The following configuration permits GET and POST calls from the example.com domain:

management.endpoints.web.cors.allowed-origins=http://example.com management.endpoints.web.cors.allowed-methods=GET,POST

For more information refer

like image 44
Abhijit Avatar answered Nov 12 '22 16:11

Abhijit