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