Spring-cloud-netflix: Feature request: preserving cache headers with zuul when using spring security

Created on 28 Mar 2018  路  10Comments  路  Source: spring-cloud/spring-cloud-netflix

When using Zuul (cloud Edgware.SR3) in spring boot (1.5.10.RELEASE), is it possible to preserve the cache control headers of an upstream system given that spring security is being used.

I think you can set zuul.ignore-security-headers=true but, in my understanding that will remove ALL security related headers (such as HSTS, Frame blocking, xss protection, HPKP etc...).

I just want to remove the default spring security no cache headers and favour the up stream response which includes public cache control (for 1 year for example).

question

Most helpful comment

Just came across with the same situation - the service behind Zuul sets some cache-control header to response, but it is cleared out while transmitting response through Zuul. Found that the both following solutions works with Edgware.SR3 Spring Cloud Release Train:

1) To explicitly set up at the Zuul gateway the headers from the service you want to ignore. If you don't do so - the list of header is initialized implicitly and Cache-Control is one of them. So list some headers without mentioning Cache-Control:
zuul.ignored-headers=X-Content-Type-Options,Strict-Transport-Security,X-Frame-Options,X-XSS-Protection

Note that, If you set zuul.ignored-headers to an empty value it leads to implicit initialization with Cache-Control among ignored headers. So don't just leave it empty.

2) To set to not ignore all security headers:
zuul.ignore-security-headers=false
The disadvantage - if the service uses Spring Security there will be duplication on Security headers in the response:
X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; mode=block
To solve this you could apply solution 1 :), or if you service is also Spring-app - disable security headers in it. For example - to disable all one could put the following to WebSecurityConfigurerAdapter:
.headers().disable()

All 10 comments

@ryanjbaxter

Proxy Response

I tried settingzuul.ignored-headers=cache-control in my application.properties and sadly nothing changed.

My response is:

< HTTP/1.1 200 
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Referrer-Policy: no-referrer
< Date: Thu, 05 Apr 2018 18:58:04 GMT
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked

Going by the documentation of the property (org.springframework.cloud.netflix.zuul.filters.ZuulProperties#ignoredHeaders) I'd assume this shouldn't work. It says:

/**
* Names of HTTP headers to ignore completely (i.e. leave them out of downstream
* requests and drop them from downstream responses).
*/
private Set ignoredHeaders = new LinkedHashSet<>();

In my case, I don't want to drop the cache-control headers from downstream responses - I want to keep them and proxy them through and not have spring security overwrite them.

Up Stream Direct Response

When talking directly to the upstream server with curl I get:

< HTTP/1.1 200 
< Cache-Control: max-age=3600, must-revalidate, public
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Thu, 05 Apr 2018 19:03:21 GMT
< 

Other Experiments

If I set zuul.ignoreSecurityHeaders=false

I get:

HTTP/1.1 200 
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Referrer-Policy: no-referrer
< Date: Thu, 05 Apr 2018 19:07:25 GMT
< Cache-Control: max-age=3600, must-revalidate, public
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked

Notice now that the cache control is there from the upstream but so is the spring security one.

and If I set zuul.ignoreSecurityHeaders=true

HTTP/1.1 200 
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Referrer-Policy: no-referrer
< Date: Thu, 05 Apr 2018 19:11:09 GMT
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked

nothing from the upstream and spring security headers are still there.

If I set both:

zuul.ignored-headers=cache-control
zuul.ignoreSecurityHeaders=false

Now the response is:

HTTP/1.1 200 
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Referrer-Policy: no-referrer
< Date: Thu, 05 Apr 2018 19:19:59 GMT
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
zuul.ignored-headers=cache-control
zuul.ignoreSecurityHeaders=true

Now the response is:

HTTP/1.1 200 
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Referrer-Policy: no-referrer
< Date: Thu, 05 Apr 2018 19:26:33 GMT
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked

Actually I think the property is zuul.ignored-headers, we might have a bug in our documentation.

@ryanjbaxter in my previous example I attempted:

zuul.ignored-headers=cache-control in my application.properties and sadly nothing changed.

Is this expected?

Just came across with the same situation - the service behind Zuul sets some cache-control header to response, but it is cleared out while transmitting response through Zuul. Found that the both following solutions works with Edgware.SR3 Spring Cloud Release Train:

1) To explicitly set up at the Zuul gateway the headers from the service you want to ignore. If you don't do so - the list of header is initialized implicitly and Cache-Control is one of them. So list some headers without mentioning Cache-Control:
zuul.ignored-headers=X-Content-Type-Options,Strict-Transport-Security,X-Frame-Options,X-XSS-Protection

Note that, If you set zuul.ignored-headers to an empty value it leads to implicit initialization with Cache-Control among ignored headers. So don't just leave it empty.

2) To set to not ignore all security headers:
zuul.ignore-security-headers=false
The disadvantage - if the service uses Spring Security there will be duplication on Security headers in the response:
X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; mode=block
To solve this you could apply solution 1 :), or if you service is also Spring-app - disable security headers in it. For example - to disable all one could put the following to WebSecurityConfigurerAdapter:
.headers().disable()

@alxkalin from what I am gathering from @davidgoate they are saying setting zuul.ignored-headers=cache-control is not working for him, you are saying it does work for you?

@ryanjbaxter, the setting should not work. Because (if I understood @davidgoate correctly) it's not the right setting to get desired behaviour - _to preserve the cache control headers of an upstream system_

Ah I understand now. @davidgoate let us know if that works.

Names of HTTP headers to ignore completely (i.e. leave them out of downstream requests and drop them from downstream responses).

@alxkalin , I also stuck exact here for a whole day. Thanks. your workround solution is really help me out, Thank you.

Closing due to age of the question. If you would like us to look at this issue, please comment and we will look at re-opening the issue.

Was this page helpful?
0 / 5 - 0 ratings