24

I tried to enable CORS globally like this:

@Configuration
@ComponentScan("com.example")
@EnableWebMvc
public class OriginFilter extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE");
    }
}

I also tried this approach:

@Configuration
public class OriginFilter implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
                .allowCredentials(true);
    }
}

But none of these worked for me.

An annotation @CrossOrigin for an individual class works, but I wanted to enable CORS it globally.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Moler
  • 955
  • 2
  • 8
  • 17
  • 1
    You can use the CorsConfigurationSource as described in [this thread](https://stackoverflow.com/a/40431994/776546). – nyxz Oct 08 '19 at 07:33

8 Answers8

55

You could indeed define your own Filter as you mentioned in your answer. Spring already has such a CorsFilter already though, so you don't have to create one yourself. Just register it as a bean and it should work:

@Bean
public CorsFilter corsFilter() {
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    final CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    // Don't do this in production, use a proper list  of allowed origins
    config.setAllowedOrigins(Collections.singletonList("*"));
    config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
    config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}
g00glen00b
  • 41,995
  • 13
  • 95
  • 133
  • 2
    Thanks I tested it and it's working. It's better approach, you are right. – Moler Aug 07 '18 at 07:48
  • 1
    But where exactly would you place the above code? We need to create a new filter with the above method? – Henry Jan 02 '20 at 06:42
  • 4
    @henry This isn't just a method, this method returns a filter (`CorsFilter` implements `Filter`). This method should be placed within a configuration class (either a class that has the `@Configuration` annotation, or the main class). – g00glen00b Jan 02 '20 at 10:32
  • 1
    This is documented [here](https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-cors-filter) – lcnicolau Feb 14 '20 at 21:03
  • Hi @g00glen00b, should I add anything to WebSecurityConfig class to configure method? – Celestine Babayaro Jul 26 '23 at 06:55
4

I solved this problem by adding filterClass

@Component
public class CORSFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept");
        response.setHeader("Access-Control-Expose-Headers", "Location");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}
Moler
  • 955
  • 2
  • 8
  • 17
3

The working global CORS configuration using WebMvcConfigurer for me without using filter.

@Configuration
public class GlobalCorsConfiguration {

    public GlobalCorsConfiguration() {
        super();
    }

    /**
     * Bean to define global CORS.
     * 
     * @return
     */
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
            }
        };
    }
}

Thanks.

Sushan Baskota
  • 315
  • 3
  • 10
3

You can also do the following to enable CORS globally in Spring Boot application. However please note that WebMvcConfigurerAdapter is deprecated.

@SuppressWarnings("deprecation")
@SpringBootApplication(exclude = org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class)
public class SpringbootMongodbDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootMongodbDemoApplication.class, args);
    }
    @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurerAdapter() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**").allowedOrigins("*");
                }
            };
        }

Also in the Controller add the following-

@PostMapping("/addfeedback")
@CrossOrigin(origins = "*")
public FeedbackForResolution addFeedback(@RequestBody FeedbackForResolution feedback) {
.
.
.
}
Hirak JD
  • 181
  • 2
  • 7
3

here is the solution for your approach. this is working fine as expected. it may be too late. but it will be useful for someone.

there are two ways to enable globally.

1.One is through creating bean. 2.other one is thorugh annotaion

1st Method:

@Configuration
public class CorsConfiguration {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedOrigins("*")
                .allowedHeaders("*");
            }
        };
    }
}

2nd method:

by adding @CrossOrigin annotation on the top of the controller class.

but First Two methods is not working for PUT Request for me. For Put Method, you can use the following approach.

The following approach will work for all the type of requests.

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("DELETE");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

}
karthick S
  • 564
  • 1
  • 9
  • 18
1

I have had issues with this problem as well and have attempted to use some of solutions listed on this page, I had little success. I am using spring boot version 2.1.2.RELEASE.

This solved it for me,

import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
blah
blah


    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); 
        config.addAllowedOrigin("http://localhost:4200");
        config.addAllowedHeader("*");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

Where blah blah is the rest of my code.

I have no idea why this method worked for me and the others did not, it allowed my typescript application making connections from localhost:4200 to connect to my spring boot application running on localhost:8080

Dave
  • 577
  • 6
  • 25
1

Hi I have gone through this issue(Global Configuration wasn't working) recently! and I found something useful.

We should NOT add backslash at the end like this http://localhost:4200/ Basically it should be http://localhost:4200 (not backslash at end)

RenceAbi
  • 522
  • 2
  • 11
  • 26
0

I fixed this issue by adding the following config class :

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

This method enables CORS requests from any origin to any endpoint in the application.

Ousama
  • 2,176
  • 3
  • 21
  • 26