5
votes

I am trying to connect angular 6 project with spring boot application. When I run angular project, it constantly gives this error, although I have installed all the dependencies and imports.

I have used following line of code in controller class.

@CrossOrigin(origins = "http://localhost:4200/", maxAge = 3600)

I have also included this SimpleCORSFilter.java file in java folder:

package com.oms;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class SimpleCORSFilter implements Filter {

private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);

public SimpleCORSFilter() {
    log.info("SimpleCORSFilter init");
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

    chain.doFilter(req, res);
}

@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void destroy() {
}

}

Also I have created proxy.conf.json file in angular project:

{
    "/api": {
      "target": "http://localhost:8080",
      "secure": false
    }
  }

This file is included like this in angular.json:

"start": "ng serve --proxy-config proxy.conf.json",

Still I am getting this error:

Access to XMLHttpRequest at 'http://localhost:8080/fetchAll' from origin 'http://localhost:4200' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.**

I referred such type of queries, but could not get the exact solution.

I am really confused, if there is any error in code? What steps should be taken to resolve this issue?

4
Change your SimpleCORSFilter.java code to have response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, X-Requested-With, remember-me"). That, add Authorization to the value. The error message, “Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response” is exactly caused by the fact the code doesn’t include Authorization in the value it’s setting for the Access-Control-Allow-Headers response header.sideshowbarker
@sideshowbarker yes, it worked. Thanks a lot!Sophia

4 Answers

3
votes

When you are using Spring Boot, I would suggest you to add a CorsFilter bean in your configurations instead of introducing a CORS filter. Let me know if this helps.

@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);
    }

Happy Coding :)

1
votes

This error is coming because request contains some additional headers which are not mentioned in your CORS filter configuration.

For adding CORS support during development, I generally prefer adding below spring configuration file. You need to have app.cors.enabled key with value true in your application configuration file (application.properties) also to make it work.

import org.springframework.context.annotation.Bean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@ConditionalOnProperty(name = "app.cors.enabled")
/**
* If the value of the key "app.cors.enabled" is true in application.properties file,
* then only this configuration will be enabled.
* 
*/
public class SpringConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/*").allowedHeaders("*").allowedOrigins("*").allowedMethods("*")
                        .allowCredentials(true);
            }
        };
    }
}

Make sure for production environment, you remove app.cors.enabled key from your configuration file or set its value to false. If you need CORS support in production environment also, make sure you use fixed values instead of allowing all values using *

Once you do that, there is no need of @CrossOrigin annotation on your controller.

1
votes

Issue is with the ordering of filters with spring boot. Add this annotation on your CORSFilter: @Order(Ordered.HIGHEST_PRECEDENCE).

This will make sure that your CORSFilter has highest precendence of execution (most prior).

0
votes

Please add a servlet filter and add the following code. It should work. Adding "Access-Control-Allow-Headers", "*" is mandatory. Creation of proxy.conf.json is not needed.

@Component

@Order(1) public class MyProjectFilter implements Filter {

@Override
public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
    response.setHeader("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE,PUT,OPTIONS");
    response.setHeader("Access-Control-Allow-Headers", "*");
    response.setHeader("Access-Control-Max-Age", "86400");
    chain.doFilter(req, res);
}

}