cors not working for my spring boot application

brain storm picture brain storm · Sep 22, 2016 · Viewed 10.1k times · Source

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.

Answer

Parth Solanki picture Parth Solanki · Sep 22, 2016

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() {}
}