文章目录
DelegatingFilterProxy过滤器和它代理的FilterChainProxy过滤器
SpringSecurity需要导入的依赖
理解几个单词的意思:
delegate:代表,委托
DelegatingFilterProxy:委托过滤器代理
FilterChainProxy:过滤器链代理
security:安全
web.xml配置
先要在web.xml文件中配置DelegatingFilterProxy过滤器的信息:
<filter>
<filter-name>filter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
疑惑
用过Spring Security的人都会熟悉以上代码,一般教程上都会说明,使用Spring Security就需要在web.xml中指定以上代码。从这个配置中,可能会给我们造成一个错觉,以为DelegatingFilterProxy类就是springSecurity的入口,但其实这个类位于spring-web这个jar下面,说明这个类本身是和springSecurity无关,那么问题来了,既然这个过滤器类本身和SpringSecurity无关,那么为什么还需要在web.xml中配置这个过滤器类的相关信息呢,为什么不直接配置FilterChainProxy的配置信息呢?
DelegatingFilterProxy类的位置如下图:
与SpringSecurity框架关系最密切的是FilterChainProxy这个过滤器,它的位置是在org.springframework.security.web中,如下图
解决疑惑
主要是因为DelegatingFilterProxy可以代理FilterChainProxy。
因为SpringSecurity的核心过滤器链主要是在SpringApplication容器里面,过滤器链的名字是FilterChainProxy,过滤器链也可以看成一个大的过滤器,然后IOC容器中的这个bean会交给DelegatingFilterProxy代理,相当于在DelegatingFilterProxy中实现了FilterChainProxy这个类,于是只需要在web.xml文件中配置DelegatingFilterProxy的相关信息就可以通过此过滤器来代理SpringSecurity中最重要的过滤器FilterChainProxy。
DelegatingFilterProxy相当于一个代理类,它会通过web.xml配置中的DelegatingFilterProxy对应的filter-name去spring的IOC容器中寻找id是filter-name的过滤器,也即是FilterChainProxy,找到之后执行DelegatingFilterProxy中对应的过滤逻辑。
那么上面的使用web.xml中配置的DelegatingFilterProxy去代理spring的IOC容器中的FilterChainProxy在源码中是怎样实现的呢?下面来分析源码:
分析源码
DelegatingFilterProxy类继承于抽象类GenericFilterBean,间接地implement 了javax.servlet.Filter接口,Servlet容器在启动时,首先会调用Filter的init方法,GenericFilterBean的作用主要是可以把Filter的初始化参数自动地set到继承于GenericFilterBean类的Filter中去。在其init方法的如下代码就是做了这个事:
首先来看一下DelegatingFilterProxy这个类的继承:
可以看出DelegatingFilterProxy继承了GenericFilterBean抽象类,而GenericFilterBean抽象类实现了javax.servlet.Filter接口,因此相当于DelegatingFilterProxy间接实现了javax.servlet.Filter接口,因此DelegatingFilterProxy也是一个过滤器。
其次就是在Sevlet容器启动的时候,也就是web.xml文件开始加载的时候会自动找到里面的DelegatingFilterProxy配置,然后调用此过滤器的init方法,但是此过滤器是没有init方法的,因此会调用父类GenericFilterBean的抽象方法给DelegatingFilterProxy初始化赋值,父类GenericFilterBean中的init方法中有一个initFilterBean方法,此方法其实是去调用DelegatingFilterProxy中的initFilterBean方法。
接下来就是回到DelegatingFilterProxy类中查看initFilterBean的源码,如下图
通过上图中的源码可以的出DelegatingFilterProxy类中的属性delegate代表的就是spring的IOC容器中的FilterChainProxy对象。
接下来查看DelegatingFilterProxy类中的initDelegate方法的源码,如下图:
然后会执行DelegatingFilterProxy的doFilter方法,doFilter方法的源码如下图:
最后是invokeDelegate的源码:
DelegatingFilterProxy过滤器的属性
在web.xml配置中
<filter>
<filter-name>filter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
有一个初始化参数是targetFilterLifecycle并且值设置成了true,targetFilterLifecycle也是DelegatingFilterProxy中的属性,有什么作用呢?targetFilterLifecycle可以让DelegatingFilterProxy代理的filter bean里init和destroy方法生效。
上面的两张图片是让DelegatingFilterProxy代理的filter也即是FilterChainProxy的init方法生效。
上面的两张图片是让DelegatingFilterProxy代理的filter也即是FilterChainProxy的destroy方法生效。