Getting Duplicate Response Headers. after Upgrading from 1.4.4 to 1.5.1

No change to my codebase, which works in Springboot 1.4.4. No Gateway Enabled Just added my own CORS filter

Below is my CORS filter code (nothing unusual there)

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements javax.servlet.Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        HttpServletRequest  req = (HttpServletRequest) request;
        // Just REPLY OK if request method is OPTIONS for CORS (pre-flight)

        res.addHeader("Access-Control-Allow-Origin", "*");
    res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");
        res.addHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With");
        if ( req.getMethod().equals("OPTIONS") ) {
        res.setStatus(HttpServletResponse.SC_OK);
        return;
    }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {}

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
}

Response Headers that i get

HTTP/1.1 403
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE, PUT, OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE, PUT, OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type
Set-Cookie: JSESSIONID=19F9B6D9F2C659ACDD5507D45F580390;path=/;HttpOnly
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 02 Feb 2017 00:35:21 GMT

Comment From: bclozel

This doesn't tell me much about the actual issue. Your filter might be called several times (the request could be dispatched several times to the servlet, Spring might have nothing to do with that) and your implementation doesn't guard against that.

If you think that Spring Framework / Spring Boot doesn't behave properly, could you create a small repro project that demonstrates the issue? Note that Spring Framework has a CORS filter implementation that is a OncePerRequestFilter to avoid being called several times per request.

Now about CORS, Spring supports quite extensively CORS already: * you can declare CORS configuration on a per controller endpoint basis or as a global configuration (see Boot reference documentation) * you can also use a CORS filter if it's really what you need (see Spring Framework reference doc)

Comment From: mrin9

The reason I think that it is SpringBoot's issue is because without changing anything in my code, the issue comes up when I upgrade to 1.5.1 and goes away when I downgrade to 1.4.4.

I am unable to use inbuilt SpringBoots's CORS annotation as specifying it at global level requires me to use @EnableWebMvc which I dont want to use for my RESTfull app.

I will try to put up a simple program to isolate and demonstrate the issue

Comment From: bclozel

Is there something preventing from using the CorsFilter provided by Spring Framework? (i.e. is there something missing from it?).

I'll wait for your repro project then!

Comment From: mrin9

The thing that I miss from SpringBoot's @CrossOrigin annotation is, it needs to be specified in each controller. If I need to make some changes, I will have to change at all the places.

The other option for the global controller as per the documentation is to use @EnableWebMvc annotation and override addCorsMappings. I am not sure what @EnableWebMvc would do in a RESTfull SpringBoot app so I am avoiding that. I am going with the 3rd option also specified in the documentation to use filter. This also suites me because I am using Spring Security for Token based authorization and is implemented using filters.

My code looks much manageable that way.

I will try to create a program this weekend to demonstrate the problem that I have. Which is generation of duplicate response headers

Comment From: mrin9

@bclozel here you go Spring Security Sample

Sample App, Just added spring security and a CORS Filter in SpringBoot 1.5.1 app

if you try to visit localhost:8080/index.html and checkout the response headers you will find the duplicate headers. Rollback to SpringBoot 1.4.3 things will look better

Comment From: wilkinsona

Your filter's registered twice. Once directly with Tomcat because it's annotated with @Component (Boot registers all Filter beans automatically) and once because you've configured Spring Security with it. You should do one or the other.

Comment From: mrin9

@wilkinsona Thanks for pointing towards the solution. May I ask what changed in 1.5.1, SpringSecurity or @Component ? coz this was working fine with 1.4.3

Comment From: wilkinsona

It's definitely not @Component. It may be a change in Spring Security but I can't be sure and, sorry, but I don't have time to investigate any further.

Comment From: ybs-tech

Hi, does the problem resolved?

Comment From: ybs-tech

I fixed this by add "zuul: ignored-headers: Access-Control-Allow-Credentials, Access-Control-Allow-Origin" in the bootstrap.yml.

Comment From: orubel

Have to add my two cents here. You might want to make sure you aren't 'curl-ing' with the '-i' flag on.

I realized I was doing this after getting the same results and turned it off. Viola! No duplicate headers. :)

Comment From: javasparx

I fixed by adding filter into cloud gateway:

spring:
   cloud:    
    gateway:
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_UNIQUE

Thank to https://lifesaver.codes/answer/doubled-cors-headers-after-upgrade-to-greenwich-728