简体   繁体   English

禁用Spring Security标头不起作用

[英]Disabling Spring Security headers does not work

I need to disable the cache control headers in my Spring Security conf. 我需要在Spring Security conf中禁用缓存控制头。

According to the documentation a simple http.headers.disable() should do it, but I still see the 根据文档,一个简单的http.headers.disable()应该这样做,但我仍然看到了

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

headers in responses. 回复中的标题。

My current security config is: 我目前的安全配置是:

http.antMatcher("/myPath/**") // "myPath" is of course not the real path
    .headers().disable()
    .authorizeRequests()
     // ... abbreviated
    .anyRequest().authenticated();

Things I've tried so far: 到目前为止我尝试过的事情:

application.properties application.properties

I added the security.headers.cache=false line, but that made no difference. 我添加了security.headers.cache=false行,但没有区别。

Using a filter 使用过滤器

I tried the following filter: 我尝试了以下过滤器:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
      @Override
      public void setHeader(String name, String value) {
        if (name.equalsIgnoreCase("Cache-Control")) {
          value = "";
        } else if (name.equalsIgnoreCase("Expires")) {
          value = "";
        } else if (name.equalsIgnoreCase("Pragma")) {
          value = "";
        }
        super.setHeader(name, value);
      }
  });
}

After adding logging I saw that this filter only writes the X-XSS-Protection header, all the cache headers are written somewhere later and this filter doesn't have access to "override" them. 添加日志记录后,我看到此过滤器仅写入X-XSS-Protection标头,所有缓存标头稍后写入某处,此过滤器无权“覆盖”它们。 This happens even if I add this filter at the last position of the security filter chain. 即使我在安全过滤器链的最后位置添加此过滤器,也会发生这种情况。

Using an interceptor 使用拦截器

I tried the following interceptor: 我试过以下拦截器:

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    String requestUri = request.getRequestURI();
    response.setHeader("Cache-Control", "max-age=3600");
    response.setHeader("Expires", "3600");
    response.setHeader("Pragma", "");
}

This (quite predictably) just added the headers, meaning that the original no-cache headers still appear in addition to the ones added by the interceptor. 这(很可预测)只是添加了标题,这意味着除了拦截器添加的标题之外,原始的no-cache标题仍会出现。

I'm at my wits end here. 我在这里结束了我的智慧。 How do I get rid of the cache control header set by Spring security? 如何摆脱Spring安全性设置的缓存控制头?

It may be help : 它可能会有所帮助:

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

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

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

You'll need a class that extends WebSecurityConfigurerAdapter with two overidden configure methods to configure the filter and the authentication provider. 您需要一个使用两个重叠配置方法扩展WebSecurityConfigurerAdapter的类来配置过滤器和身份验证提供程序。 For example, the following works at a bare minimum: 例如,以下工作至少是:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfigDemo extends WebSecurityConfigurerAdapter {

    @Autowired
    private DemoAuthenticationProvider demoAuthenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {        

    // Prevent the HTTP response header of "Pragma: no-cache".
    http.headers().cacheControl().disable();

    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {        
        auth.authenticationProvider(demoAuthenticationProvider);        
    }    

}

You can also disabe Spring Security completely for public static resources as following (in the same class as above): 您还可以完全取消Spring Security的公共静态资源,如下所示(与上面相同的类):

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/static/public/**");
}

This requires configuring two resource handlers to get cache control headers right: 这需要配置两个资源处理程序以正确获取缓存控制头:

@Configuration
public class MvcConfigurer extends WebMvcConfigurerAdapter
        implements EmbeddedServletContainerCustomizer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // Resources without Spring Security. No cache control response headers.
        registry.addResourceHandler("/static/public/**")
            .addResourceLocations("classpath:/static/public/");

        // Resources controlled by Spring Security, which
        // adds "Cache-Control: must-revalidate".
        registry.addResourceHandler("/static/**")
            .addResourceLocations("classpath:/static/")
            .setCachePeriod(3600*24);
    }
}

So, I found the answer myself: I finally made the Cache-Control header to change its value by creating a new entry in my yml configuration file called spring.resources.cachePeriod and set it to a value different than 0 . 所以,我自己找到了答案:我终于通过在我的yml配置文件spring.resources.cachePeriod创建一个新条目并将其设置为不同于0的值来使Cache-Control标头更改其值。 The bad thing is that all resources use this setting, so no way to make it different depending on the resource, as far as I know. 坏的是所有资源都使用这个设置,所以根据资源的不同,没有办法让它变得不同,据我所知。

The answer to this question helped a lot. 这个问题的答案帮助很大。

So I had a similar problem, wanting most of my REST endpoints to have the standard "don't cache me" headers Spring is injecting, but on one endpoint I want to insert my own. 所以我有一个类似的问题,希望我的大多数REST端点都有标准的“不要缓存我”标题Spring注入,但在一个端点我想插入自己的。

Specifying your own in the HttpHeaders object you give to the ResponseEntry does not work. 在您给予ResponseEntry的HttpHeaders对象中指定自己的对象不起作用。

What DOES WORK is to explicitly set the headers DIRECTLY on the HttpServletResponse. 什么工作是在HttpServletResponse上直接显式设置标题。

Spring is setting "Cache-Control", "Pragma" and "Expires". Spring正在设置“Cache-Control”,“Pragma”和“Expires”。 The following demonstrates how to override and set for a 1 minute caching: 以下演示了如何覆盖和设置1分钟缓存:

response.setHeader("Cache-Control", "max-age=60");
response.setHeader("Pragma", "");
HttpHeaders headers = new HttpHeaders();
headers.setExpires(System.currentTimeMillis()+60000);
return new ResponseEntity<>(body, headers, HttpStatus.OK);

I had this issue after enabling OpenId Connect through @EnableOAuth2Sso on my application class. 在我的应用程序类上通过@EnableOAuth2Sso启用OpenId Connect后,我遇到了这个问题。 After about six hours of debugging and reading through docs, it turned out that @EnableOAuth2Sso MUST be placed on WebSecurityConfigurerAdapter or custom settings will be overridden by default settings: 经过大约六个小时的调试和阅读文档后,发现@EnableOAuth2Sso必须放在WebSecurityConfigurerAdapter否则默认设置将覆盖自定义设置:

Good

// In Application.java
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

//In WebSecurity.java
@Configuration
@EnableOAuth2Sso  // <- This MUST be here, not above
public class WebSecurity extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.headers().disable();
    }
}

Bad

// In Application.java
@SpringBootApplication
@EnableOAuth2Sso  // <- Will overwrite config below
public class Application {
    //...
}

@Configuration
public class WebSecurity extends WebSecurityConfigurerAdapter {
    //...
}

You are right that using 你是对的

http
    .headers().disable()
    ...

will disable your headers. 将禁用您的标头。 If you only want cache control disabled, you can use the following: 如果您只想禁用缓存控制,则可以使用以下命令:

http
    .headers()
        .cacheControl().disable()
        .and()
    ...

I have posted a sample that demonstrates this working along with a test . 我发布了一个示例 ,证明了这一点与测试一起工作。

My guess is the problem you are having is that you have multiple HttpSecurity configurations. 我的猜测是你遇到的问题是你有多个HttpSecurity配置。 Remember that if you have: 请记住,如果你有:

http
    .antMatchers("/myPath/**")
    ...

Only URLs that start with /myPath/ will be impacted. 只有以/myPath/开头的网址才会受到影响。 Additionally, if you have multiple HttpSecurity instances each HttpSecurity instance is considered in order and only the first HttpSecurity instance is used. 此外,如果您有多个HttpSecurity实例, HttpSecurity顺序考虑每个HttpSecurity实例,并且仅使用第一个HttpSecurity实例。 For example if you have: 例如,如果你有:

@Configuration
@Order(1)
public class MyPathAdminWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatchers("/myPath/admin/**")
            .authorizeRequests()
                .anyRequest().hasRole("ADMIN");
    }
}

@Configuration
@Order(2)
public class MyPathWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatchers("/myPath/**")
            .headers()
                .cacheControl().disable();
    }
}

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated();
    }
}

If you request /myPath/admin/abc 如果你请求/ myPath / admin / abc

First MyPathAdminWebSecurityConfig is considered. 首先考虑MyPathAdminWebSecurityConfig Since /myPath/admin/ starts with /myPath/admin/ we will use MyPathAdminWebSecurityConfig and not consider any other configuration. 既然/myPath/admin/始于/myPath/admin/我们将使用MyPathAdminWebSecurityConfig和不考虑任何其他配置。 This means you will expect to get headers back for this request. 这意味着您将期望为此请求返回标头。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM