Tomcat阀强制特定的Cache-Control标头

时间:2018-12-17 14:29:13

标签: java spring-security tomcat8 tomcat-valve

我想在响应中正确设置Cache-Control和ETag标头。为此,我已通过Spring安全配置禁用了请求缓存:

httpSecurity.headers().cacheControl().disable();

然后在返回响应时:

ResponseEntity.ok()
        .header("Cache-Control", "max-age=60")
        .header("ETag", "my-tag")
        .build()

从某种意义上讲,似乎没有默认的spring安全缓存控制标头返回(默认情况下,我认为它们返回“ no-cache,no-store,max-age = 0,must-revalidate”),并且我的标题出现在响应中。但是那里还有其他东西:

Cache-Control: private
Expires: Thu, 01 Jan 1970 00:00:00 GMT
ETag: "0.42.1-20181213080300000"
Cache-Control: max-age=60
...other headers

较低的缓存标头是我的,而顶部的标头是不需要的。它们似乎来自org.apache.catalina.authenticator.AuthenticatorBase,它似乎是所使用的嵌入式Tomcat的一部分。我一直无法找到一种方法来访问和修改此特定类的配置。

请提供有关如何清除不需要的标头的建议。

我正在使用Spring Boot 1.5.18.RELEASE

1 个答案:

答案 0 :(得分:0)

为了更改Valve的配置,我不得不使用EmbeddedServletContainerCustomizer在适当的生命周期阶段从上下文中对其进行查找,如下所示。

@Component
public class TomcatCacheControlCustomizer implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        if(container instanceof TomcatEmbeddedServletContainerFactory){
            TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) container;
            containerFactory.addContextLifecycleListeners((LifecycleListener) event -> {
                Context context = (Context) event.getLifecycle();
                if(event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)){
                    if(context.getPipeline() != null){
                        Pipeline pipeline = context.getPipeline();
                        if(pipeline.getValves() != null){
                            Optional<Valve> authenticatorBase = Arrays.stream(pipeline.getValves()).filter(v -> v instanceof AuthenticatorBase).findFirst();
                            if(authenticatorBase.isPresent()){
                                ((AuthenticatorBase) authenticatorBase.get()).setDisableProxyCaching(false);
                            }
                        }
                    }
                }
            });
        }
    }

}

更新AuthenticatorBase的配置后,不需要的Cache-Control标头不再添加到响应中,仅保留了我的自定义标头。