Spring Security - No way to avoid cache-control

2020-03-18 04:00发布

问题:

I have an application and use a controller mapping of spring to load images to my users. (InputStream, response, etc).

In my controller I set headers to cache-control, baseaded on files, etc. But there's always pragma: no-cache and Cache-Control:"max-age=0" inside all requests, and that's replace my response settings.

I was trying everything to solve this, but nothing works.

I already read all page and try everything I found about that: http://docs.spring.io/autorepo/docs/spring-security/3.2.0.CI-SNAPSHOT/reference/html/headers.html

My spring security.xml has:

    <security:headers disabled="true"/>

Anyone have a good idea to solve this?

Remember that to load the images I need to load through my controller, I never call static directly.

回答1:

The Cache-Control headers can be controlled on a per action basis by overriding them in the HttpServletResponse:

@RequestMapping(value = "/foo", method = RequestMethod.GET)
public String someAction(HttpServletResponse response) {
    response.setHeader("Cache-Control", "no-transform, public, max-age=86400");

    // ...
}

No need to fiddle with the Spring Security configuration.

See http://docs.spring.io/spring-security/site/docs/current/reference/html/headers.html#headers-cache-control.



回答2:

In case one uses Java based configuration, cache control headers can be disabled this way:

@Configuration
@EnableWebMvcSecurity
class SpringWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.headers().cacheControl().disable();
    }
}

This will remove CacheControlHeadersWriter and Spring won't write cache control headers any more.



回答3:

Per Spring Security reference (3.2.0) you've linked to,

All of the default headers can be easily added using the element with no child elements

Simply adding headers by itself will turn on all child elements (e.g. cache control, xxs, ...). Either don't include headers at all or explicitly specify which child elements you want to enable.

BTW, I don't think disabled is an attribute of headers (for 3.2.0). If you're using version 4.0, there is a disabled attribute as well as disabled-defaults, which might be the one you want.



回答4:

Adding to aha's answer. You also need to override the Pragma header with some garbage.

@RequestMapping(value = "/foo", method = RequestMethod.GET)
public String someAction(HttpServletResponse response) {
    response.setHeader("Cache-Control", "no-transform, public, max-age=86400");
    response.setHeader("Pragma", "");
    // ...
}

The Expires header also still shows in the response, but seems to be overridden by the Cache-Control header in most browsers.



回答5:

It has been sometime - but while researching on the same problem, I found this post and this worked or me -

disable caching for specific url in spring security

The beauty of the solution referred above is that it enables each header specifically using its original class, and uses antmatchers to align specific request paths to the respective header. In my case, I used a separate Cache reference for my static resources with cache expiry set and another one for all jsps with no cache. Since it is an ant matcher, the controller uri can be matched using the same approach.