You can selectively add no cache headers to just index.html using Spring Security xml configuartion like this:
<security:http>
[intercept-url, etc omitted...]
<security:headers>
<!-- selectively applied to dynamic pages only via pattern matching, -->
<security:header ref="noCacheHeaders"/>
</security:headers>
</security:http>
<bean id="noCacheHeaders" class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
<constructor-arg>
<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg value="/index.html"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.web.header.writers.CacheControlHeadersWriter"/>
</constructor-arg>
</bean>
However, the usual pattern if using Spring Security is to set no cache by default to all pages, and then selectively turn those headers off for static resources that
- don't contain sensitive data
- aren't dynamic
To accomplish this feat, you have to explicitly define all headers you wish to apply in both cases, and select the pages via complementary request matcher patterns. For example, in an app where static, cacheable resources are found under /static
and its subdirectories, and all dynamic pages mapped to controllers have the .htm
extension, you can use this configuration:
<security:http>
[...]
<security:headers>
<!-- selectively applied to static pages only via pattern matching, see DelegatingRequestMatcherHeaderWriter below-->
<security:header ref="cacheStaticsHeaders" />
<!-- selectively applied to dynamic pages only via pattern matching, as above, see below -->
<security:header ref="xXssProtectionHeader" />
<security:header ref="noCacheHeaders"/>
<security:header ref="xContentHeader"/>
<security:header ref="hstsHeader"/>
<security:header ref="xFrameHeader"/>
</security:headers>
</security:http>
<!-- set far future caching on static resources -->
<bean id="cacheStaticsHeaders" class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
<constructor-arg>
<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg value="/static/**"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.web.header.writers.StaticHeadersWriter">
<constructor-arg name="headers">
<list>
<bean class="org.springframework.security.web.header.Header">
<constructor-arg name="headerName" value="cache-control"></constructor-arg>
<constructor-arg name="headerValues" value="max-age=31536000"/>
</bean>
<bean class="org.springframework.security.web.header.Header">
<constructor-arg name="headerName" value="Expires"></constructor-arg>
<constructor-arg name="headerValues" value="31536000"/>
</bean>
</list>
</constructor-arg>
</bean>
</constructor-arg>
</bean>
<!-- all the following header writers applied to dynamic, shouldn't be cached pages -->
<bean id="xXssProtectionHeader" class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
<constructor-arg>
<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg value="/**/*.htm"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.web.header.writers.XXssProtectionHeaderWriter"/>
</constructor-arg>
</bean>
<bean id="noCacheHeaders" class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
<constructor-arg>
<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg value="/**/*.htm"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.web.header.writers.CacheControlHeadersWriter"/>
</constructor-arg>
</bean>
<bean id="xContentHeader" class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
<constructor-arg>
<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg value="/**/*.htm"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.web.header.writers.XContentTypeOptionsHeaderWriter"/>
</constructor-arg>
</bean>
<bean id="hstsHeader" class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
<constructor-arg>
<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg value="/**/*.htm"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.web.header.writers.HstsHeaderWriter"/>
</constructor-arg>
</bean>
<bean id="xFrameHeader" class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
<constructor-arg>
<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg value="/**/*.htm"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"/>
</constructor-arg>
</bean>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…