Sophia
Sophia

Reputation: 145

Angular 6 + Spring Boot: Error: "from origin 'http://localhost:4200' has been blocked by CORS policy"

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?

Upvotes: 5

Views: 8905

Answers (6)

Willy Kipchumba
Willy Kipchumba

Reputation: 1

@Bean
public WebMvcConfigurer corsConfigurer()
{
   String[] allowDomains = new String[2];
   allowDomains[0] = "http://localhost:4200";
   allowDomains[1] = "http://localhost:8080";

   System.out.println("CORS configuration....");
   return new WebMvcConfigurer() {
      @Override
      public void addCorsMappings(CorsRegistry registry) {
         registry.addMapping("/**").allowedOrigins(allowDomains);
      }
   };
}

Upvotes: 0

Nimasha Madhushani
Nimasha Madhushani

Reputation: 325

Because of the spring security, this might happen. You can build a class and include the below-mentioned code.

    package com.myapp.springboot.configs;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class WebMvcConfiguration implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/*").
            allowedOrigins("*").
            allowedMethods("*").
            allowedHeaders("*").
            allowCredentials(true);
        }
    }

Upvotes: 0

Anupam
Anupam

Reputation: 47

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

}

Upvotes: 0

Jignesh M. Khatri
Jignesh M. Khatri

Reputation: 1596

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).

Upvotes: 1

Pratik Ambani
Pratik Ambani

Reputation: 2570

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 :)

Upvotes: 5

Vikas Sachdeva
Vikas Sachdeva

Reputation: 5813

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.

Upvotes: 1

Related Questions