在网上看各种SpringSecurity教程时,都讲到了SpringSecurity的Filter顺序。但是一直不知道这个顺序在源码中是如何体现的。今天一步一步的查找,最终找到顺序是在FilterComparator中定义的。

先看一下代码:

/**
* An internal use only {@link Comparator} that sorts the Security {@link Filter}
* instances to ensure they are in the correct order.
*
* @author Rob Winch
* @since 3.2
*/ @SuppressWarnings("serial")
final class FilterComparator implements Comparator<Filter>, Serializable {
private static final int STEP = ;
private Map<String, Integer> filterToOrder = new HashMap<String, Integer>(); FilterComparator() {
int order = ;
put(ChannelProcessingFilter.class, order);
order += STEP;
put(ConcurrentSessionFilter.class, order);
order += STEP;
put(WebAsyncManagerIntegrationFilter.class, order);
order += STEP;
put(SecurityContextPersistenceFilter.class, order);
order += STEP;
put(HeaderWriterFilter.class, order);
order += STEP;
put(CsrfFilter.class, order);
order += STEP;
put(LogoutFilter.class, order);
order += STEP;
put(X509AuthenticationFilter.class, order);
order += STEP;
put(AbstractPreAuthenticatedProcessingFilter.class, order);
order += STEP;
filterToOrder.put("org.springframework.security.cas.web.CasAuthenticationFilter",
order);
order += STEP;
put(UsernamePasswordAuthenticationFilter.class, order);
order += STEP;
put(ConcurrentSessionFilter.class, order);
order += STEP;
filterToOrder.put(
"org.springframework.security.openid.OpenIDAuthenticationFilter", order);
order += STEP;
put(DefaultLoginPageGeneratingFilter.class, order);
order += STEP;
put(ConcurrentSessionFilter.class, order);
order += STEP;
put(DigestAuthenticationFilter.class, order);
order += STEP;
put(BasicAuthenticationFilter.class, order);
order += STEP;
put(RequestCacheAwareFilter.class, order);
order += STEP;
put(SecurityContextHolderAwareRequestFilter.class, order);
order += STEP;
put(JaasApiIntegrationFilter.class, order);
order += STEP;
put(RememberMeAuthenticationFilter.class, order);
order += STEP;
put(AnonymousAuthenticationFilter.class, order);
order += STEP;
put(SessionManagementFilter.class, order);
order += STEP;
put(ExceptionTranslationFilter.class, order);
order += STEP;
put(FilterSecurityInterceptor.class, order);
order += STEP;
put(SwitchUserFilter.class, order);
} public int compare(Filter lhs, Filter rhs) {
Integer left = getOrder(lhs.getClass());
Integer right = getOrder(rhs.getClass());
return left - right;
} /**
* Determines if a particular {@link Filter} is registered to be sorted
*
* @param filter
* @return
*/
public boolean isRegistered(Class<? extends Filter> filter) {
return getOrder(filter) != null;
} /**
* Registers a {@link Filter} to exist after a particular {@link Filter} that is
* already registered.
* @param filter the {@link Filter} to register
* @param afterFilter the {@link Filter} that is already registered and that
* {@code filter} should be placed after.
*/
public void registerAfter(Class<? extends Filter> filter,
Class<? extends Filter> afterFilter) {
Integer position = getOrder(afterFilter);
if (position == null) {
throw new IllegalArgumentException(
"Cannot register after unregistered Filter " + afterFilter);
} put(filter, position + );
} /**
* Registers a {@link Filter} to exist before a particular {@link Filter} that is
* already registered.
* @param filter the {@link Filter} to register
* @param beforeFilter the {@link Filter} that is already registered and that
* {@code filter} should be placed before.
*/
public void registerBefore(Class<? extends Filter> filter,
Class<? extends Filter> beforeFilter) {
Integer position = getOrder(beforeFilter);
if (position == null) {
throw new IllegalArgumentException(
"Cannot register after unregistered Filter " + beforeFilter);
} put(filter, position - );
} private void put(Class<? extends Filter> filter, int position) {
String className = filter.getName();
filterToOrder.put(className, position);
} /**
* Gets the order of a particular {@link Filter} class taking into consideration
* superclasses.
*
* @param clazz the {@link Filter} class to determine the sort order
* @return the sort order or null if not defined
*/
private Integer getOrder(Class<?> clazz) {
while (clazz != null) {
Integer result = filterToOrder.get(clazz.getName());
if (result != null) {
return result;
}
clazz = clazz.getSuperclass();
}
return null;
}
}

这个顺序和很多教程讲解的是一致的。但是其中有一些Filter多次执行,还没明白什么原因。继续研究中。

对于主要Filter的作用,可以参考这篇文章  http://blog.csdn.net/win7system/article/details/51659182

我的SpringSecurity版本是4.0.1

SpringSecurity的Filter执行顺序在源码中的体现的更多相关文章

  1. Django中CBV的执行顺序之源码解析

    浅析Django中的CBV的执行顺序 下图为CBV方式的执行顺序,大概执行流程如下: 其中浅蓝色为在假设自己写的类,即Test类中没有dispatch方法的情况下的执行顺序,当自己的类中有dispat ...

  2. 服务网关zuul之二:过滤器--请求过滤执行过程(源码分析)

    Zuul的核心是一系列的过滤器,这些过滤器可以完成以下功能: 身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求. 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生成 ...

  3. Go Revel - Filter(过滤器)源码分析

    在 Go Revel - server.go 源码分析 http://www.cnblogs.com/hangxin1940/p/3265538.html 说到revel框架很多重要的东西都Filte ...

  4. ASP.NET MVC Filters 4种默认过滤器的使用【附示例】 数据库常见死锁原因及处理 .NET源码中的链表 多线程下C#如何保证线程安全? .net实现支付宝在线支付 彻头彻尾理解单例模式与多线程 App.Config详解及读写操作 判断客户端是iOS还是Android,判断是不是在微信浏览器打开

    ASP.NET MVC Filters 4种默认过滤器的使用[附示例]   过滤器(Filters)的出现使得我们可以在ASP.NET MVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响 ...

  5. 从express源码中探析其路由机制

    引言 在web开发中,一个简化的处理流程就是:客户端发起请求,然后服务端进行处理,最后返回相关数据.不管对于哪种语言哪种框架,除去细节的处理,简化后的模型都是一样的.客户端要发起请求,首先需要一个标识 ...

  6. Android 源码中的设计模式

    最近看了一些android的源码,发现设计模式无处不在啊!感觉有点乱,于是决定要把设计模式好好梳理一下,于是有了这篇文章. 面向对象的六大原则 单一职责原则 所谓职责是指类变化的原因.如果一个类有多于 ...

  7. Python源码中的PyCodeObject

    1.Python程序的执行过程 Python解释器(interpreter)在执行任何一个Python程序文件时,首先进行的动作都是先对文件中的Python源代码进行编译,编译的主要结果是产生的一组P ...

  8. 源码中修改Android的开机画面和动画【转】

    本文转载自:http://blog.csdn.net/dddxxxx/article/details/54343976 参照文章:http://blog.csdn.net/a345017062/art ...

  9. 挖掘隐藏在源码中的Vue技巧!

    前言 最近关于Vue的技巧文章大热,我自己也写过一篇(vue开发中的"骚操作"),但这篇文章的技巧是能在Vue的文档中找到蛛丝马迹的,而有些文章说的技巧在Vue文档中根本找不到踪迹 ...

随机推荐

  1. HDU - 5201 :The Monkey King (组合数 & 容斥)

    As everyone known, The Monkey King is Son Goku. He and his offspring live in Mountain of Flowers and ...

  2. java 华容道 迷弟版(向 xd-女神 吴嘉欣致敬)

    // Person.java 每个方块人物是一个类 package test; import javax.swing.*; import java.awt.*; import java.awt.eve ...

  3. Codeforces Round #519

    题目链接:传送门   A. Elections (思维+暴力) 思路: 从最小的k开始枚举就好了- -. #include <bits/stdc++.h> using namespace ...

  4. A Spy in the Metro(UVA 1025 ACM/ICPC World Finals2003)

    ---恢复内容开始--- 题意:有n(2<=n<=50)个车站,从左到右编号为1~n,有M1辆列车从第1站向右开,还有M2辆列车从第N站向左开.在时刻0,间谍从第1站出发,目的是在时刻T( ...

  5. Linux使用sshfs挂载远程目录到本地

    1安装sshfs [root@iZwz9hy7gff0kpg1swp1d3Z ~]# yum install sshfs 2创建本地目录 [root@iZwz9hy7gff0kpg1swp1d3Z ~ ...

  6. acm 2001

    格式化输出 //////////////////////////////////////////////////////////////////////////////// #include<i ...

  7. PS学习之合成特效:被风沙侵蚀的动物们

    素材 大象 尘埃 裂纹 沙子 土地 正式操作: 打开PS 新建一个文件 选国际标准纸张  给分辨率为72(分辨率越大越占内存) 然后确定  将图片旋转90度(图像——旋转——(顺/逆)90度) 下面选 ...

  8. ios-根据单元格里的控件tag值,在方法外获得对应的section与row的值

    在cell的代理方法里:cellForRowAtIndexPath btn.tag = indexPath.section *100 + indexPath.row; [cell.exitPerson ...

  9. imrersize函数

    imrersize函数: 用法:imresize(图像I,method,倍数) 'nearest'(默认值)最近邻插值'bilinear'双线性插值'bicubic'双三次插值 使用方法: clear ...

  10. C++编译器报错汇总

    1.error: ‘Person’ was not declared in this scope(1)若是一个类或函数的命名空间对使用者不可见(2)成员(静态)函数没有通过对象名或类名进行调用(3)虽 ...