cors not working for my spring boot application

10,313

Solution 1

I think you need to add cors origin filter , I am not sure but I think this below solution is works for you.

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.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter {

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

        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        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");
        if(request.getMethod().equals(HttpMethod.OPTIONS.name())){
            response.setStatus(HttpStatus.NO_CONTENT.value());
        }else{
            chain.doFilter(req, res);
        }
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}
}

Solution 2

As I explained here it is required to set the corsfilter to be loaded before errorPageFilter from spring boot. Otherwise CORS support will be broken and the required headers won't be introduced. This can be accomplished with the @Order(Ordered.HIGHEST_PRECEDENCE) as indicated above.

Share:
10,313
brain storm
Author by

brain storm

Updated on June 27, 2022

Comments

  • brain storm
    brain storm almost 2 years

    Here is my webConfig

    @Configuration
    @EnableWebMvc
    public class WebConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**");
        }
    }
    

    I have a /health endpoint, which returns some health data and it works fine.

    Here is junit test

    @Test
        public void corsTest() {
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.ORIGIN, "http://localhost:9000");
            HttpEntity<?> requestEntity = new HttpEntity(headers);
            ResponseEntity<Status> entity = this.restTemplate.exchange("/health", HttpMethod.GET, requestEntity, Status.class);
            assertEquals(HttpStatus.OK, entity.getStatusCode());
            assertEquals("http://localhost:9000", entity.getHeaders().getAccessControlAllowOrigin()); //6
            Status health = entity.getBody();
            assertThat(health.getAppName()).isEqualTo(appName);
        }
    

    Test fails at line 6. if comment-out that line, the test passes. Through debugger, I found that entity.getHeaders().getAccessControlAllowOrigin() is null. I used this sample app as reference and it works fine. but for my application it fails.

    when I use javascript to call the /health api, I can see the cors works. If I comment out, webConfig class, I get error in javascript. Debugging more at javascript shows that cors response header is not set but the request served successfully when webconfig is enabled.

    so definitely cors works. It is the test that is failing. so I am guessing test is not seeing it for reasons I don't know.