一、过滤器
Spring Security
的
Servlet
支持基于
Servlet
过滤器,因此首先了解过滤器的作用会很有帮助。
下图为单个
HTTP
请求的处理程序的典型分层。
客户端向应用程序发送一个请求,运行容器创建一个
FilterChain
(过滤链),其中包括所有的
Filter
实例和
Servlet
。过滤器根据
URI
路径处理请求和响应。
在一个
SpringMvc
(
Spring Boot
)应用程序中,一般只有一个
Servlet
实例,也就是
DispatcherServlet
,他们按照指定的顺序(每个
Filter
实例实例的顺序非常重要),共同协作。
一个简单的自定义过滤器代码示例:
// 使用@ServletComponentScan添加在启动类上扫描该自定义过滤器@WebFilter(filterName ="simpleFilter", urlPatterns ={"/*"})@Slf4jpublicclassSimpleFilter3implementsFilter{publicvoidinit(FilterConfig filterConfig)throwsServletException{
log.info("初始化");}@OverridepublicvoiddoFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain)throwsIOException,ServletException{
log.info("业务处理开始");
filterChain.doFilter(servletRequest, servletResponse);
log.info("业务处理结束");}publicvoiddestroy(){
log.info("销毁");}}
二、DelegatingFilterProxy
Spring
提供了一个名为
DelegatingFilterProxy
的实现,它允许
Servlet
容器和
Spring IoC
容器的生命周期之间进行桥接。
Servlet
容器使用自己的标准注册
Filter
实例,但它不知道
Spring IoC
容器中定义的过滤器
Bean
。在有了
DelegatingFilterProxy
后就可以很方便的在
Servlet
中使用
Spring IoC
容器来管理过滤器
Bean
。
在请求响应过程中,
DelegatingFilterProxy
从
Spring IoC
容器中查询注册的过滤器
Bean
对象,然后调用
Bean
的过滤方法。
下图为
DelegatingFilterProxy
是如何让使用
Filter
实例和
FilterChain
的。
从
DelegatingFilterProxy
源码中可以看到该类包含了
Spring IoC
容器和被代理的过滤器:
一个简单的DelegatingFilterProxy使用代码示例:
// Spring定义的Bean Filter@Component("simpleFilter")@Slf4jpublicclassSimpleFilter2implementsFilter{publicvoidinit(FilterConfig filterConfig)throwsServletException{
log.info("初始化");}@OverridepublicvoiddoFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain)throwsIOException,ServletException{
log.info("业务处理开始");
filterChain.doFilter(servletRequest, servletResponse);
log.info("业务处理结束");}publicvoiddestroy(){
log.info("销毁");}}@ConfigurationpublicclassSimpleConfig{@BeanpublicDelegatingFilterProxyRegistrationBeandelegatingFilterProxyRegistrationBean(){DelegatingFilterProxyRegistrationBean delegatingFilterProxy =newDelegatingFilterProxyRegistrationBean("simpleFilter");
delegatingFilterProxy.addUrlPatterns("/*");
delegatingFilterProxy.setOrder(-5);Map<String,String> initParameters =newHashMap<>();
initParameters.put("targetFilterLifecycle","true");
delegatingFilterProxy.setInitParameters(initParameters);return delegatingFilterProxy;}}
三、FilterChainProxy
Spring Security
提供
FilterChainProxy
代理类,是
Spring Security
使用的核心,用于代理
Spring Security
中所有的
SecurityFilterChain
,而在
SecurityFilterChain
中又包含多个
Spring Security
声明的
Filter
下图
FilterChainProxy
在整个请求响应过程中的作用。
从
FilterChainProxy
源码中可以看到该类代理了
Spring Security
中所有的
SecurityFilterChain
:
FilterChainProxy
本质上是一个特殊的过滤器,通过
DelegatingFilterProxy
进行代理,所有其也是一个
Bean
对象。
在
SecurityFilterChain
过滤链中通常都是
Bean
对象,通过
FilterChainProxy
进行注册与直接通过
Servlet
容器或通过
DelegatingFilterProxy
进行注册相比,
FilterChainProxy
注册有很多优势:
- 它为
Spring Security
的所有Servlet
支持提供了一个起点,如果需要对Spring Security
的Servlet
支持进行故障诊断可以在在FilterchainProxy
中添加一个调试点。 - 可以执行一些不被视为可有可无的任务,例如,清除了
SecurityContext
以避免内存泄漏、应用Spring Security
的HttpFirewall
来保护应用程序免受某些类型的攻击 - 在确定何时应该调用
SecurityFilterChain
方面提供了更大的灵活性,在Servlet
容器中,Filter
实例仅基于URL
被调用。FilterChainProxy
可以通过使用RequestMatcher
接口,根据HttpServletRequest
中的任何内容确定调用。
版权归原作者 gmHappy 所有, 如有侵权,请联系我们删除。