通过前面Spring Security提供的各种Filter的分析,大体上知道每个Filter具体的用途了。 Spring Security一共提供了20个Filter,我目前只分析了13个(如果http的auto-config="true",那默认的filter列表都包含在这13个里面了),另外7个在后面的源码分析中碰到时会逐个讲解。 在分析http标签时,已经提到filter排序的问题了,但是没有深入。
现在再回头看filter是如何排序的。下面的代码片段截取自HttpSecurityBeanDefinitionParser类,
-
- List<OrderDecorator> unorderedFilterChain = new ArrayList<OrderDecorator>();
-
- unorderedFilterChain.addAll(httpBldr.getFilters());
- unorderedFilterChain.addAll(authBldr.getFilters());
-
- BeanDefinition requestCacheAwareFilter = new RootBeanDefinition(RequestCacheAwareFilter.class);
- requestCacheAwareFilter.getPropertyValues().addPropertyValue("requestCache", authBldr.getRequestCache());
- unorderedFilterChain.add(new OrderDecorator(requestCacheAwareFilter, REQUEST_CACHE_FILTER));
-
- unorderedFilterChain.addAll(buildCustomFilterList(element, pc));
-
- Collections.sort(unorderedFilterChain, new OrderComparator());
-
-
- checkFilterChainOrder(unorderedFilterChain, pc, source);
-
- List<BeanMetadataElement> filterChain = new ManagedList<BeanMetadataElement>();
-
- for (OrderDecorator od : unorderedFilterChain) {
- filterChain.add(od.bean);
- }
细心的同学会发现httpBldr.getFilters()、authBldr.getFilters()两个方法返回的就是OrderDecorator对象的集合列表。并且OrderDecorator对象已经将filter与SecurityFilters中的order关联了起来
- unorderedFilterChain.addAll(httpBldr.getFilters());
- unorderedFilterChain.addAll(authBldr.getFilters());
顺便看一下创建自定义过滤器部分
- List<OrderDecorator> buildCustomFilterList(Element element, ParserContext pc) {
- List<Element> customFilterElts = DomUtils.getChildElementsByTagName(element, Elements.CUSTOM_FILTER);
- List<OrderDecorator> customFilters = new ArrayList<OrderDecorator>();
-
- final String ATT_AFTER = "after";
- final String ATT_BEFORE = "before";
- final String ATT_POSITION = "position";
-
- for (Element elt: customFilterElts) {
- String after = elt.getAttribute(ATT_AFTER);
- String before = elt.getAttribute(ATT_BEFORE);
- String position = elt.getAttribute(ATT_POSITION);
-
- String ref = elt.getAttribute(ATT_REF);
-
- if (!StringUtils.hasText(ref)) {
- pc.getReaderContext().error("The '" + ATT_REF + "' attribute must be supplied", pc.extractSource(elt));
- }
-
- RuntimeBeanReference bean = new RuntimeBeanReference(ref);
-
- if(WebConfigUtils.countNonEmpty(new String[] {after, before, position}) != 1) {
- pc.getReaderContext().error("A single '" + ATT_AFTER + "', '" + ATT_BEFORE + "', or '" +
- ATT_POSITION + "' attribute must be supplied", pc.extractSource(elt));
- }
-
- if (StringUtils.hasText(position)) {
- customFilters.add(new OrderDecorator(bean, SecurityFilters.valueOf(position)));
-
- } else if (StringUtils.hasText(after)) {
- SecurityFilters order = SecurityFilters.valueOf(after);
- if (order == SecurityFilters.LAST) {
- customFilters.add(new OrderDecorator(bean, SecurityFilters.LAST));
- } else {
- customFilters.add(new OrderDecorator(bean, order.getOrder() + 1));
- }
-
- } else if (StringUtils.hasText(before)) {
- SecurityFilters order = SecurityFilters.valueOf(before);
- if (order == SecurityFilters.FIRST) {
- customFilters.add(new OrderDecorator(bean, SecurityFilters.FIRST));
- } else {
- customFilters.add(new OrderDecorator(bean, order.getOrder() - 1));
- }
- }
- }
-
- return customFilters;
- }
这里用到三个重要的与排序相关的类及枚举,分别是OrderDecorator、OrderComparator以及SecurityFilters枚举 首先看SecurityFilters枚举定义
- enum SecurityFilters {
- FIRST (Integer.MIN_VALUE),
-
- CHANNEL_FILTER,
-
- CONCURRENT_SESSION_FILTER,
-
- SECURITY_CONTEXT_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,
- 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;
- }
- }
由此可见,该类维护了Spring Security中每个filter的顺序
接着看OrderDecorator类。这个类实现org.springframework.core.Ordered接口
- class OrderDecorator implements Ordered {
- BeanMetadataElement bean;
- int order;
-
- public OrderDecorator(BeanMetadataElement bean, SecurityFilters filterOrder) {
- this.bean = bean;
- this.order = filterOrder.getOrder();
- }
-
- public OrderDecorator(BeanMetadataElement bean, int order) {
- this.bean = bean;
- this.order = order;
- }
-
- public int getOrder() {
- return order;
- }
-
- public String toString() {
- return bean + ", order = " + order;
- }
- }
OrderComparator类的路径是org.springframework.core.OrderComparator,实际上是spring core包的一个比较器,可以顺便看下OrderComparator源码。下面截取的只是部分核心代码
- public int compare(Object o1, Object o2) {
- boolean p1 = (o1 instanceof PriorityOrdered);
- boolean p2 = (o2 instanceof PriorityOrdered);
- if (p1 && !p2) {
- return -1;
- }
- else if (p2 && !p1) {
- return 1;
- }
-
-
-
- int i1 = getOrder(o1);
- int i2 = getOrder(o2);
-
- return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
- }
-
- protected int getOrder(Object obj) {
- return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : Ordered.LOWEST_PRECEDENCE);
- }
通过以上的分析,可以总结如下
1.由SecurityFilters维持位置order 2.由OrderDecorator维持filter与order的对应关系 3.由OrderComparator负责比较OrderDecorator的先后顺序
附上默认的过滤器顺序列表
order |
过滤器名称 |
100 |
ChannelProcessingFilter |
200 |
ConcurrentSessionFilter |
300 |
SecurityContextPersistenceFilter |
400 |
LogoutFilter |
500 |
X509AuthenticationFilter |
600 |
RequestHeaderAuthenticationFilter |
700 |
CasAuthenticationFilter |
800 |
UsernamePasswordAuthenticationFilter |
900 |
OpenIDAuthenticationFilter |
1000 |
DefaultLoginPageGeneratingFilter |
1100 |
DigestAuthenticationFilter |
1200 |
BasicAuthenticationFilter |
1300 |
RequestCacheAwareFilter |
1400 |
SecurityContextHolderAwareRequestFilter |
1500 |
RememberMeAuthenticationFilter |
1600 |
AnonymousAuthenticationFilter |
1700 |
SessionManagementFilter |
1800 |
ExceptionTranslationFilter |
1900 |
FilterSecurityInterceptor |
2000 |
SwitchUserFilter | 以上标注红色的都已经分析完毕
|