5

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?

2
  • 1
    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. Commented Jun 12, 2019 at 12:28
  • @sideshowbarker yes, it worked. Thanks a lot! Commented Jun 13, 2019 at 4:47

6 Answers 6

5

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

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, I tried adding this file in configurations, it worked. Thanks for the help.
Glad it worked for you, importantly hope you've understood the issue
i added this in my config class "public class AuthServerConfig extends AuthorizationServerConfigurerAdapter implements Filter" and added this method "@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException" ... still no luck
1

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.

2 Comments

Can you explain the use of app.cors.enabled in the code?
app.cors.enabled is just for making this CORS support configurable. Generally, with angular app development, we need to enable CORS support in Java backend but once you merge build code of angular with backend app, this support is not required so just by this configuration key app.cors.enabled, you can disable CORS support in production environment.
1

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

3 Comments

When I enter this annotation, "Ordered" was left unresolved.
What do you mean by unresolved? You are not getting its package? It should be imported from org.springframework.core.Ordered
Yes, I was not getting the package, but now this import helped. Thanks.
0

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

}

2 Comments

I tried the above and it still threw CORS preflight error. Am I required to use Spring Security in this scenario? Works without the CORS filter in local and does not work in production.
Your UI code must interact through a common gateway (webserver) with backend application servers through HTTPS protocol. You need to setup digital certificates to that common gateway.
0

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

Comments

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

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.