Spring Security之 web.xml 源码分析(三)
本篇文章我们来分析一下在
web.xml
中DelegatingFilterProxy
的名字<filter-name>
为什么必须是springSecurityFilterChain
和springSecurityFilterChain
究竟做了什么
-
在
web.xml
配置了一个DelegatingFilterProxy
的filter,而DelegatingFilterProxy
的名字<filter-name>
必须是springSecurityFilterChain
,因为springSecurityFilterChain
是Spring容器帮我们去初始化的一个filter
-
打开执行类
DelegatingFilterProxy
的源码,发现DelegatingFilterProxy
它并不是filter
,它继承的类GenericFilterBean
才实现了Filter
接口
-
我们关注下
DelegatingFilterProxy
这个类中的doFilter()
方法,而在doFilter()
方法,doFilter()
方法中具体使用的是delegate
这个Filter
,DelegatingFilterProxy
并不是真正的Filter
,真正做事的是delegate
-
delegate
这个属性在DelegatingFilterProxy
这个类开头已经有了申明
-
然后我们再来看到
DelegatingFilterProxy
类中的initFilterBean()
方法中找到delegate
的创建,里面有个targetBeanName
通过getFilterName()
获取到值
-
再找到
getFilterName()
这个方法,而这个方法就是去web.xml中获取<filter-name>
值给targetBeanName
,这里就回答了第一个问题,因为getFilterName()
这个方法是到web.xml中获取<filter-name>
值给targetBeanName
,所以我们web.xml中<filter-name>
的值必须是springSecurityFilterChain
-
我们再回到
initFilterBean()
方法中的delegate
,delegate
它是通过initDelegate(wac)
去注入的
8.所以我们再来看看initDelegate(wac)
这个方法是怎么执行的,它里面再次出现了delegate
和targetBeanName
这两个属性,所以最终把targetBeanName
的值赋值给了delegate
9.当initFilterBean()
方法中的delegate
获取到值后,delegate
把值传到最初我们看到的doFilter()
,再把值赋值给delegateToUse
-
DelegatingFilterProxy
类中的invokeDelegate()
给我们描述了delegateToUse
在做什么事
-
查看
invokeDelegate()
方法调用了doFilter(request, response, filterChain)
方法
-
再查看
doFilter(request, response, filterChain)
方法,发现调用了Filter
接口
-
此接口的
doFilter()
方法实际是找了具体实现类FilterChainProxy
的doFilter()
-
在
FilterChainProxy
中不管什么情况都会执行doFilterInternal(request, response, chain)
这个方法
- 查看
doFilterInternal(request, response, chain)
这个方法,里面会获取一个List集合,里面就是Spring Security
在运行中所有默认filter
,然乎一个个加载去执行
Spring Security
在运行了哪些默认filter
,我们可以查看SecurityFilters
这个类
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.http;
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
/**
* Stores the default order numbers of all Spring Security filters for use in
* configuration.
*
* @author Luke Taylor
* @author Rob Winch
*/
enum SecurityFilters {
FIRST(Integer.MIN_VALUE),
CHANNEL_FILTER,
SECURITY_CONTEXT_FILTER,
CONCURRENT_SESSION_FILTER,
WEB_ASYNC_MANAGER_FILTER /** {@link WebAsyncManagerIntegrationFilter} */,
HEADERS_FILTER, CORS_FILTER,
CSRF_FILTER,
LOGOUT_FILTER,
X509_FILTER,
PRE_AUTH_FILTER,
CAS_FILTER,
FORM_LOGIN_FILTER,
OPENID_FILTER,
LOGIN_PAGE_FILTER,
DIGEST_AUTH_FILTER,
BASIC_AUTH_FILTER,
REQUEST_CACHE_FILTER,
SERVLET_API_SUPPORT_FILTER,
JAAS_API_SUPPORT_FILTER,
REMEMBER_ME_FILTER,
ANONYMOUS_FILTER,
SESSION_MANAGEMENT_FILTER,
EXCEPTION_TRANSLATION_FILTER,
FILTER_SECURITY_INTERCEPTOR,
SWITCH_USER_FILTER,
LAST(Integer.MAX_VALUE);
private static final int INTERVAL = 100;
private final int order;
private SecurityFilters() {
order = ordinal() * INTERVAL;
}
private SecurityFilters(int order) {
this.order = order;
}
public int getOrder() {
return order;
}
}