Pooja Mahapatra
Pooja Mahapatra

Reputation: 125

Cors filter not working for spring boot

I am working on spring boot filters. I have registered the CORS bean as

@Bean
public FilterRegistrationBean simpleCORSFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        SimpleCORSFilter filter = new SimpleCORSFilter();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

        config.applyPermitDefaultValues();
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(Integer.MAX_VALUE);
        bean.setFilter(filter);
        return bean;
    }

I have written a filter class for the same. Though the class is getting instantiated but the request from UI is failing here.

@Component
public class SimpleCORSFilter extends OncePerRequestFilter {
    private static final Logger LOGGER = LoggerFactory.getLogger(SimpleCORSFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
            LOGGER.info("start");

                response.setHeader("Access-Control-Allow-Origin", "*");
                response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
                response.setHeader("Access-Control-Max-Age", "3600");
                response.setHeader("Access-Control-Allow-Credentials", "true");
                response.setHeader("Access-Control-Allow-Headers", "Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,auth-token");
                if(request.getMethod().equals(HttpMethod.OPTIONS.name())){
                    response.setStatus(HttpStatus.NO_CONTENT.value());
                }else{
                    AuthenticationRequestWrapper requestAuth = new AuthenticationRequestWrapper((HttpServletRequest) request);
                    filterChain.doFilter(requestAuth, response);
                }
                LOGGER.info("end");
    }
}

But still I am getting the following error

cors header ‘access-control-allow-origin’ missing

Upvotes: 2

Views: 8155

Answers (4)

Juani
Juani

Reputation: 1

I had the same issue. I thought that my spring cors configuration was wrong, but what I realized was that the request must fulfill some requirements:

the method must be OPTIONS
the presence of the Origin header
the presence of the Access-Control-Allow-Methods header

I found that here

Try this:

1-Just add the @CrossOrigin annotation to your controller
2-Send your request with this 2 headers using OPTIONS method:
Access-Control-Request-Method:GET
Origin:*

You should get your Access-Control-Allow-Origin:*

Juani

Upvotes: 0

Mickael
Mickael

Reputation: 4558

According to offcial Spring Boot documentation :

Here's an example of how to configure CORS with annotations and filters :

Enabling CORS

Controller method CORS configuration

So that the RESTful web service will include CORS access control headers in its response, you just have to add a @CrossOrigin annotation to the handler method:

src/main/java/hello/GreetingController.java

@CrossOrigin(origins = "http://localhost:9000")
@GetMapping("/greeting")
public Greeting greeting(@RequestParam(required=false, defaultValue="World") String name) {
    System.out.println("==== in greeting ====");
    return new Greeting(counter.incrementAndGet(), String.format(template, name));
}

Global CORS configuration

As an alternative to fine-grained annotation-based configuration, you can also define some global CORS configuration as well. This is similar to using a Filter based solution, but can be declared within Spring MVC and combined with fine-grained @CrossOrigin configuration. By default all origins and GET, HEAD and POST methods are allowed.

src/main/java/hello/GreetingController.java

@GetMapping("/greeting-javaconfig")
public Greeting greetingWithJavaconfig(@RequestParam(required=false, defaultValue="World") String name) {
    System.out.println("==== in greeting ====");
    return new Greeting(counter.incrementAndGet(), String.format(template, name));
}

src/main/java/hello/Application.java

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:9000");
        }
    };
}

Upvotes: 1

Georgi  Stoyanov
Georgi Stoyanov

Reputation: 539

I don't think that you need bean for that. Also adding @Order(Ordered.HIGHEST_PRECEDENCE) just after @Component maybe will solve your problem. This will tell spring that this configuration should be with highest precedence. And in order to be consistent use HttpServletResponse.SC_OK instead HttpStatus.NO_CONTENT.value()

Upvotes: 2

Bk Santiago
Bk Santiago

Reputation: 1573

I suggest to try using this one https://gist.github.com/keesun/2245179

Works for me, then add it to WebMvcConfigurer

public class Interceptors implements WebMvcConfigurer {
  private final CorsInterceptor corsInterceptor;

  @Autowired
  public Interceptors(CorsInterceptor corsInterceptor) {
    this.corsInterceptor = corsInterceptor;
  }

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(this.corsInterceptor).addPathPatterns("/**");
  }
}

I also added @Configuration to the CorsInterceptor class

Upvotes: 1

Related Questions