Search code examples
springannotationsspring-bootservlet-filtersetag

Add ShallowEtagHeaderFilter in Spring Boot MVC


I'm trying to adjust my application configuration in order to setup ETag support.

I have just checked this SO question, so let me say where my code is different from it:

  1. I don't use any xml configuration file whatsoever.
  2. I'm using different configuration classes for each aspect of the system. My WebConfig looks like this:

@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = { "xxx", "yyy" })
public class WebConfig extends WebMvcConfigurerAdapter {

   @Bean
   public Filter shallowETagHeaderFilter() {
        return new ShallowEtagHeaderFilter();
   }
      ...
}

  1. And my SecurityConfig looks like this:

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        ...

        @Override
        protected void configure(final HttpSecurity http) throws Exception {
            http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().exceptionHandling()
                        .authenticationEntryPoint(authenticationEntryPoint())
                .and().authorizeRequests()
                        .antMatchers(HttpMethod.GET, "/**").authenticated()
                        .antMatchers(HttpMethod.POST, "/**").authenticated()
                        .antMatchers(HttpMethod.HEAD, "/**").authenticated()
            .and().csrf().disable()    
            .addFilterBefore(authenticationTokenProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
        }

    }

  1. I also have an initializer class, which is empty:

    @Order(value=1)
    public class SecurityWebAppInitializer extends AbstractSecurityWebApplicationInitializer {

    }

I don't see anywhere the ShallowEtagHeaderFilter been added to the default chain or anything, how can I use it in this setup?


Solution

  • Alright,

    According to this post:

    [...] To help mitigate this Spring Security has added cache control support which will insert the following headers into you response.

    Cache-Control: no-cache, no-store, max-age=0, must-revalidate

    Pragma: no-cache

    Expires: 0

    So, what happened is that ETag support was added, but Spring Security invalidated it in the response. It seems that if you want to use both Spring Security and ETag support, you need to declare the following code line (highlighted by the arrow):

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        ...
    
        @Override
        protected void configure(final HttpSecurity http) throws Exception {
            http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().exceptionHandling()
                        .authenticationEntryPoint(authenticationEntryPoint())
                .and().authorizeRequests()
                        .antMatchers(HttpMethod.GET, "/**").authenticated()
                        .antMatchers(HttpMethod.POST, "/**").authenticated()
                        .antMatchers(HttpMethod.HEAD, "/**").authenticated()
            .and().csrf().disable()    
            .addFilterBefore(authenticationTokenProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
            ===> http.headers().cacheControl().disable();
        }
    
    }