如何向 Spring Security 忽略的请求添加标头

Posted

技术标签:

【中文标题】如何向 Spring Security 忽略的请求添加标头【英文标题】:How to add headers to requests ignored by Spring Security 【发布时间】:2017-11-24 04:04:24 【问题描述】:

我对Spring Security的配置是

@Override
  public void configure(WebSecurity web) throws Exception 
    web
      .ignoring()
         .antMatchers("/resources/**"); // #3
  

Taken from here. ignorig 的文档说

允许添加 Spring Security 应该忽略的 RequestMatcher 实例。 ... 通常,注册的请求应该只是静态资源的请求。

我想为从资源提供的文件添加一些标题。 例如:Strict-Transport-Security: max-age=31536000X-Content-Type-Options: nosniff

我该怎么做?

【问题讨论】:

您找到解决问题的方法了吗?我有同样的问题,想利用 Spring Security 而不是制作自制的 servlet 过滤器。 我做了,但我的解决方案在没有解释的情况下被否决了。所以我删除了它。期待你的到来。 您介意再分享一次吗?您是使用 Spring Security 还是最终创建了一个 servlet 过滤器? 取消删除我的答案。 您的解决方案是什么?不赞成也不接受我的回答。 【参考方案1】:

一个解决方案将其更改为

protected void configure(HttpSecurity http) throws Exception 
    http.authorizeRequests().antMatchers("/resources/**").permitAll()
       .and()
       .antMatcher("/resources/**").headers().cacheControl()

示例如何允许缓存控制标头 PLUS ALL DEFAULT SPRING SECURITY HEADERS。

【讨论】:

还有别的办法吗?过滤器? 我的 WebSecurity 类中没有“.authorizeRequests()”方法。我正在使用 Spring 1.2。 感谢您的编辑。这并不能“解决”我的问题,因为“WebSecurity.ignored()”禁用了整个“尝试验证”的事情。而你的解决方案没有。我已经发布了我是如何做到的。 ;) 你能解释一下“WebSecurity.ignored()”是什么意思吗? WebSecurity.ignored() 本来是您原始答案的web.ignoring(),抱歉打错了。据我所知,此声明确实禁用了整个HttpSecurity 配置,但我无论如何,已经找到了运行过滤器的技巧。就像我在回答中描述的那样。【参考方案2】:

我也遇到过同样的问题。当我忽略 WebSecurity 中的特定请求时,标头消失了。

我通过对添加我的标头的每个请求应用过滤器来修复丢失的标头。

@Override
protected void configure(HttpSecurity http) throws Exception 
    http
        .addFilterBefore(securityHeaderFilter, BasicAuthenticationFilter.class)
        ...

过滤器代码如下所示。 这里需要注意的重要一点是,过滤器必须声明为@Component当您错过@Component 注释时,过滤器将被忽略。

@Component
public class SecurityHeaderFilter implements Filter 

    @Override
    public void init(FilterConfig fc) throws ServletException 
        // Do nothing
    

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException 
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        httpServletResponse.setHeader(
                "custom-header1", "header-value1");
        httpServletResponse.setHeader(
                "custom-header2", "header-value2");
        chain.doFilter(request, response);
    

    @Override
    public void destroy() 
        // Do nothing
    

【讨论】:

【参考方案3】:

我使用了以下解决方案:

@Bean
    public FilterRegistrationBean setHeaders() 
        HstsHeaderWriter hstsHeaderWriter = new HstsHeaderWriter(31536000, true);
        XContentTypeOptionsHeaderWriter xContentTypeOptionsHeaderWriter = new XContentTypeOptionsHeaderWriter();
        List<HeaderWriter> headerWriters = new ArrayList<>();
        headerWriters.add(hstsHeaderWriter);
        headerWriters.add(xContentTypeOptionsHeaderWriter);
        HeaderWriterFilter headerWriterFilter = new HeaderWriterFilter(headerWriters);
        FilterRegistrationBean bean = new FilterRegistrationBean(headerWriterFilter);
        bean.setOrder(1);
        return bean;
    

上面的 bean 将在所有资源(甚至是忽略的资源)上全局添加一个过滤器。您可以检查 org.springframework.security.web.header.HeaderWriter.java 的各种实现以获取不同类型的安全标头,并将它们全部添加到 HeaderWriterFilter.java。

【讨论】:

以上是关于如何向 Spring Security 忽略的请求添加标头的主要内容,如果未能解决你的问题,请参考以下文章

如何在spring boot项目中忽略特定URL的spring security CSRF

如何忽略 Spring Security 中的端点?

如何在Spring Security中忽略端点?

Grails spring security在向控制器操作发出ajax请求时出现403错误

Spring Boot 如何忽略 HttpStatus 异常

Spring 3,Spring Security,LDAP,如何向 LDAP 添加角色?