Spring Security - 无法避免缓存控制

Posted

技术标签:

【中文标题】Spring Security - 无法避免缓存控制【英文标题】:Spring Security - No way to avoid cache-control 【发布时间】:2015-10-03 11:04:50 【问题描述】:

我有一个应用程序并使用 spring 的控制器映射将图像加载给我的用户。 (输入流、响应等)。

在我的控制器中,我将标头设置为缓存控制、基于文件等。但是在所有请求中总是有 pragma: no-cache 和 Cache-Control:"max-age=0" ,这替换了我的响应设置.

我想尽一切办法解决这个问题,但没有任何效果。

我已经阅读了所有页面并尝试了我发现的所有内容: http://docs.spring.io/autorepo/docs/spring-security/3.2.0.CI-SNAPSHOT/reference/html/headers.html

我的 spring security.xml 有:

    <security:headers disabled="true"/>

谁有解决这个问题的好主意?

请记住,要加载我需要通过控制器加载的图像,我从不直接调用 static。

【问题讨论】:

您能否提供用于在控制器中设置标题的代码?如果完全删除 Spring Security,问题是否仍然存在? 【参考方案1】:

根据您链接到的Spring Security reference (3.2.0),

使用没有子元素的元素可以轻松添加所有默认标题

单独添加headers 将打开所有子元素(例如缓存控制、xxs、...)。要么根本不包含标题,要么明确指定要启用的子元素。

顺便说一句,我不认为disabled 是标题的属性(对于 3.2.0)。如果您使用的是version 4.0,则有一个disabled 属性以及disabled-defaults,这可能是您想要的。

【讨论】:

现在试过了,没有解决。我想删除我的请求的“无缓存”,不包括它们。 你尝试了什么?你能展示一下你更新后的配置是什么样子的吗? 当然,现在的配置是: 对于安全版本会开启所有默认的headers(包括缓存控制)。如果您不需要任何标头,只需删除 。如果您需要一些标题,请明确列出它们。如果您的安全版本是 4.0,请尝试添加属性 disabled-defaults="true" 我也试过了,把所有东西都拿出来,还是一样。我不需要任何东西,但它在我的应用程序中保持无缓存。【参考方案2】:

已经有一段时间了 - 但是在研究同样的问题时,我发现了这篇文章,这对我来说很有效 -

disable caching for specific url in spring security

上面提到的解决方案的美妙之处在于它允许每个标头专门使用其原始类,并使用 antmatchers 将特定的请求路径与相应的标头对齐。在我的例子中,我为我的静态资源使用了一个单独的缓存引用,并设置了缓存到期,另一个用于所有没有缓存的 jsps。由于它是一个蚂蚁匹配器,控制器 uri 可以使用相同的方法进行匹配。

【讨论】:

【参考方案3】:

如果使用基于 Java 的配置,可以通过这种方式禁用缓存控制标头:

@Configuration
@EnableWebMvcSecurity
class SpringWebSecurityConfig extends WebSecurityConfigurerAdapter 

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

这将删除 CacheControlHeadersWriter 并且 Spring 将不再写入缓存控制标头。

【讨论】:

我在哪里放置这个配置? 感谢您的回答。为我工作。 禁用默认的 Spring 安全行为是个坏主意。你在这里阅读更多:baeldung.com/spring-security-cache-control-headers【参考方案4】:

Cache-Control 标头可以通过在 HttpServletResponse 中覆盖它们来基于每个操作进行控制:

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

    // ...

无需摆弄 Spring Security 配置。

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

【讨论】:

这是我发现的唯一可行的方法。非常感谢! 非常感谢。您的解决方案节省了大量时间。 这将复制标题而不是覆盖它。我收到no-cache, no-store, max-age=0, must-revalidate, max-age=7200 @Kumait 适用于 Spring 5.1.9【参考方案5】:

添加到aha 的答案。您还需要用一些垃圾覆盖 Pragma 标头。

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

Expires 标头仍然显示在响应中,但在大多数浏览器中似乎被 Cache-Control 标头覆盖。

【讨论】:

【参考方案6】:

下面的代码应该在 spring 5.X 中为你工作

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.headers()
        .defaultsDisabled()
        .cacheControl();
    

【讨论】:

以上是关于Spring Security - 无法避免缓存控制的主要内容,如果未能解决你的问题,请参考以下文章

如何配置 Spring Security 以避免 405 Method Not Allowed for PUT request from Angular?

无法为会话序列化会话属性 SPRING_SECURITY_CONTEXT

Spring Security权限缓存

如何在 spring-security 5.2 中增加 RemoteJWKSet 缓存 TTL

Spring security 如何设置才能避免拦截到静态资源

本地数据库上的 Spring Security LDAP 用户数据缓存