返回介绍

8.1 HttpFirewall 简介

发布于 2025-04-26 13:16:46 字数 2222 浏览 0 评论 0 收藏

在 Servlet 容器规范中,为 HttpServletRequest 定义了一些属性,如 contextPath、servletPath、pathInfo、queryString 等,这些属性都可以通过 get 方法获取。

然而,在 Servlet 容器规范中并没有定义这些属性可以包含哪些值,例如在 servletPath 和 pathInfo 中都可以包含 RFC2396 规范(https://www.ietf.org/rfc/rfc2396.txt)中定义的参数,不同容器对此处理方案也不同,有的容器会对此进行预处理,有的容器则不会。这种比较混乱的处理方式有可能会造成安全隐患,因此 Spring Security 中通过 HttpFirewall 来检查请求路径以及参数是否合法,如果合法,才会进入到过滤器链中进行处理。

HttpFirewall 是一个接口,它只有两个方法:

    public interface HttpFirewall {
       FirewalledRequest getFirewalledRequest(HttpServletRequest request)
               throws RequestRejectedException;
       HttpServletResponse getFirewalledResponse(HttpServletResponse response);
    }

getFirewalledRequest 方法用来对请求对象进行检验并封装,getFirewalledResponse 方法则对响应对象进行封装。

FirewalledRequest 是封装后的请求类,但实际上该类只是在 HttpServletRequestWrapper 的基础上增加了 reset 方法。当 Spring Security 过滤器链执行完毕时,由 FilterChainProxy 负责调用该 reset 方法,以便重置全部或者部分属性。

FirewalledResponse 是封装后的响应类,该类主要重写了 sendRedirect、setHeader、addHeader 以及 addCookie 四个方法,在每一个方法中都对其参数进行校验,以确保参数中不含有\r 和\n。

HttpFirewall 一共有两个实现类,如图 8-1 所示。

图 8-1 HttpFirewall 的两个实现类

- DefaultHttpFirewall:虽然名字中包含 Default,但这并不是框架默认使用的 Http 防火墙,它只是一个检查相对宽松的防火墙。

- StrictHttpFirewall:这是一个检查严格的 Http 防火墙,也是框架默认使用的 Http 防火墙。

HttpFirewall 中对请求的合法性校验在 FilterChainProxy#doFilterInternal 方法中触发,具体可以参考 4.1.4 小节,这里不再赘述。

需要注意的是 HttpFirewall 的配置位置,在 Spring Security 框架中有两个地方涉及了 HttpFirewall 实例的获取:

(1)在 FilterChainProxy 属性定义中,默认创建的 HttpFirewall 实例就是 StrictHttpFirewall。

(2)FilterChainProxy 是在 WebSecurity#performBuild 方法中构建的,而 WebSecurity 实现了 ApplicationContextAware 接口,并实现了接口中的 setApplicationContext 方法,在该方法中,从 Spring 容器中查找到 HttpFirewall 对象并赋值给 httpFirewall 属性。最终在 performBuild 方法中,将 FilterChainProxy 对象构建成功后,如果 httpFirewall 不为 null,就把 httpFirewall 配置给 FilterChainProxy 对象。

根据以上两点可以得出:如果 Spring 容器中存在 HttpFirewall 实例,则最终使用 Spring 容器提供的 HttpFirewall 实例;如果 Spring 容器中不存在 HttpFirewall 实例,则使用 FilterChainProxy 中默认定义的 StrictHttpFirewall。进而可知,如果开发者不想使用默认的 StrictHttpFirewall 实例,则只需要自己提供一个 HttpFirewall 并注册到 Spring 容器中即可。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。