Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cors not working for my spring boot application

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.

like image 555
brain storm Avatar asked Sep 22 '16 17:09

brain storm


People also ask

How do you solve the CORS problem in Spring boot?

Enable CORS in Controller Method We need to set the origins for RESTful web service by using @CrossOrigin annotation for the controller method. This @CrossOrigin annotation supports specific REST API, and not for the entire application.

How do I enable CORS Spring boot?

Enabling CORS Configuration Globally in Spring Webflux To define CORS globally in a Spring Webflux application, we use the WebfluxConfigurer and override the addCorsMappings() . Similar to Spring MVC, it uses a CorsConfiguration with defaults that can be overridden as required.

Why CORS is not working?

Or, your API fails and shows a CORS error in the console. This happens because the same-origin policy is part of the browser's security model which allows websites to request data from APIs of the same URL but blocks those of different URLs. Browsers do this by adding an ORIGIN key in the request.

How do I fix invalid CORS request?

Go to https://www.getpostman.com/docs/capture in your chrome browser. Click on interceptor extension and then choose add to chrome. Once it is added there is a new icon top right of both the browser and postman that looks like a traffic light. In postman click this and it turns green.


2 Answers

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() {}
}
like image 125
Parth Solanki Avatar answered Nov 11 '22 11:11

Parth Solanki


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.

like image 25
megalucio Avatar answered Nov 11 '22 10:11

megalucio