spring security源码分析之一springSecurityFilterChain

1. spring和spring security的集成,配置web.xml如下:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-security.xml
        </param-value>
    </context-param>

    <!-- Spring Security -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2. springSecurityFilterChain的来龙去脉

在org.springframework.security.config包里定义了该名称:

    /** External alias for FilterChainProxy bean, for use in web.xml files */
    public static final String SPRING_SECURITY_FILTER_CHAIN = "springSecurityFilterChain";
使用springSecurityFilterChain的地方:HttpSecurityBeanDefinitionParser.java 该类建立Http 安全体系:过滤器栈和受保护的url。
    static void registerFilterChainProxyIfNecessary(ParserContext pc, Object source) {
        if (pc.getRegistry().containsBeanDefinition(BeanIds.FILTER_CHAIN_PROXY)) {
            return;
        }
        // Not already registered, so register the list of filter chains and the FilterChainProxy
        BeanDefinition listFactoryBean = new RootBeanDefinition(ListFactoryBean.class);
        listFactoryBean.getPropertyValues().add("sourceList", new ManagedList());
        pc.registerBeanComponent(new BeanComponentDefinition(listFactoryBean, BeanIds.FILTER_CHAINS));

        BeanDefinitionBuilder fcpBldr = BeanDefinitionBuilder.rootBeanDefinition(FilterChainProxy.class);
        fcpBldr.getRawBeanDefinition().setSource(source);
        fcpBldr.addConstructorArgReference(BeanIds.FILTER_CHAINS);
        fcpBldr.addPropertyValue("filterChainValidator", new RootBeanDefinition(DefaultFilterChainValidator.class));
        BeanDefinition fcpBean = fcpBldr.getBeanDefinition();
        pc.registerBeanComponent(new BeanComponentDefinition(fcpBean, BeanIds.FILTER_CHAIN_PROXY));
        pc.getRegistry().registerAlias(BeanIds.FILTER_CHAIN_PROXY, BeanIds.SPRING_SECURITY_FILTER_CHAIN);
    }

}

从上面的代码可以看出,springSecurityFilterChain是DelegatingFilterProxy的代理对象。

3.FilterChainProxy

代理一组spring管理的filter bean来处理request。从spring security2.0以后,除非你需要对filter chain的内容进行严格的控制,否则你就无需显式的在context中配置一个FilterChainProxy。默认的<security:http />命名空间配置选项可以处理绝大部分应用场景。

通过在你的应用中的web.xml中增加一个名为DelegatingFilterProxy标准的spring声明,就可以将FilterChaiProxy链接到servlet 容器的filter chain。

3.1 配置

从spring security 3.1版本,FilterChainProxy通过一组SecurityFilterChain实例来配置,每个SecurityFilterChain实例包含一个RequestMacher和一组匹配request的Filter。

大部分应用只需要包含一个简单的filter chain,若你使用命名空间,你无需显式的设置chain;若你需要一个精确的 控制,你可以使用<filter-chain>命名空间元素。它定义了一个urI匹配模式和一组逗号分隔的、应用到request和url匹配的filter。实例如下:

<bean id="myfilterChainProxy" class="org.springframework.security.util.FilterChainProxy">
     <constructor-arg>
         <util:list>
             <security:filter-chain pattern="/do/not/filter*" filters="none"/>
             <security:filter-chain pattern="/**" filters="filter1,filter2,filter3"/>
         </util:list>
     </constructor-arg>
 </bean>

3.2 request处理

  HttpFirewall实例用来验证接收的request请求,并且创建一个新的包装后的请求,这个新包装的请求提供了和原请求一致的路径值。

  FilterChainProxy使用firewall实例来获取应用到filter chain的request请求和response响应对象。当request请求通过security filter chain,将调用reset方法,此时将会返回servletPath和pathInfo的原始值,而不是security 模式匹配后的修改值。

3.3 Filter生命周期

注意,servlet容器中的filter生命周期和Ioc容器中的filter生命周期不一致。因此建议你使用Ioc容器而不是servlet容器来管理你增加到应用上下文的filter 的生命周期。

3.4 SecurityFilterChain

定义了一个filter chain,它能够和HttpServletRequest进行匹配,匹配是为了决定是否需要应用到该request请求。

4. filters预览

  那么spring security有哪些filter呢?

SecurityFilters.java定义了默认的filter及其顺序:

 FIRST (Integer.MIN_VALUE),
    CHANNEL_FILTER,
    SECURITY_CONTEXT_FILTER,
    CONCURRENT_SESSION_FILTER,
    /** {@link WebAsyncManagerIntegrationFilter} */
    WEB_ASYNC_MANAGER_FILTER,
    HEADERS_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;

测试:

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(SecurityFilters.CHANNEL_FILTER.getOrder());
        System.out.println(SecurityFilters.SECURITY_CONTEXT_FILTER.getOrder());
        System.out.println(SecurityFilters.CONCURRENT_SESSION_FILTER.getOrder());
    }

结果如下:

100
200
300

以此类推:

默认的过滤器顺序列表
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

5. filters架构层次

时间: 2024-11-03 02:40:03

spring security源码分析之一springSecurityFilterChain的相关文章

spring security源码分析之二---web包分析

Spring 是一个非常流行和成功的 Java 应用开发框架.Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案.一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分.用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统.用户认证一般要求用户提供用户名和密码.系统通过校验用户名和密码来完成认证过程.用户授权指的是验证某个用户是否有权限执行某个操作.在一

spring security源码分析之core包

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作.[1] 1. core模块 认证Authentication

Spring AMQP 源码分析 05 - 异常处理

### 准备 ## 目标 了解 Spring AMQP Message Listener 如何处理异常 ## 前置知识 <Spring AMQP 源码分析 04 - MessageListener> ## 相关资源 Offical doc:<http://docs.spring.io/spring-amqp/docs/1.7.3.RELEASE/reference/html/_reference.html#exception-handling> Sample code:<ht

Spring AMQP 源码分析 07 - MessageListenerAdapter

### 准备 ## 目标 了解 Spring AMQP 如何用 POJO 处理消息 ## 前置知识 <Spring AMQP 源码分析 04 - MessageListener> ## 相关资源 Offical doc:<http://docs.spring.io/spring-amqp/docs/1.7.3.RELEASE/reference/html/_reference.html#message-listener-adapter> Sample code:<https:

Spring AMQP 源码分析 06 - 手动消息确认

### 准备 ## 目标 了解 Spring AMQP 如何手动确认消息已成功消费 ## 前置知识 <Spring AMQP 源码分析 04 - MessageListener> ## 相关资源 Offical doc:<http://docs.spring.io/spring-amqp/docs/1.7.3.RELEASE/reference/html/_reference.html#message-listener-adapter> Sample code:<https:

Spring AMQP 源码分析 08 - XML 配置

### 准备 ## 目标 通过 XML 配置文件使用 Spring AMQP ## 前置知识 <Spring AMQP 源码分析 07 - MessageListenerAdapter> ## 相关资源 Sample code:<https://github.com/gordonklg/study>,rabbitmq module 源码版本:Spring AMQP 1.7.3.RELEASE ## 测试代码 gordon.study.rabbitmq.springamqp.XmlC

spring事务源码分析结合mybatis源码(一)

最近想提升,苦逼程序猿,想了想还是拿最熟悉,之前也一直想看但没看的spring源码来看吧,正好最近在弄事务这部分的东西,就看了下,同时写下随笔记录下,以备后查. spring tx源码分析 这里只分析简单事务也就是DataSourceTransactionManager 首先肯定找入口了,看过spring源码的同学一定都会找spring tx的入口就是在TxAdviceBeanDefinitionParser这里将解析tx的配置,生成TransactionInterceptor对象,这个也就是一

Spring IoC 源码分析 (基于注解) 之 包扫描

在上篇文章Spring IoC 源码分析 (基于注解) 一我们分析到,我们通过AnnotationConfigApplicationContext类传入一个包路径启动Spring之后,会首先初始化包扫描的过滤规则.那我们今天就来看下包扫描的具体过程. 还是先看下面的代码: AnnotationConfigApplicationContext类 //该构造函数会自动扫描以给定的包及其子包下的所有类,并自动识别所有的Spring Bean,将其注册到容器中 public AnnotationConf

spring transaction源码分析--事务架构

1. 引言  事务特性 事务是并发控制的单元,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位.通过事务将逻辑相关的一组操作绑定在一起,以便服务器 保持数据的完整性.事务通常是以begin transaction开始,以commit或rollback结束.Commint表示提交,即提交事务的所有操作.具体地说就是将事务中所有对数据的更新写回到磁盘上的物理数据库中去,事务正常结束.Rollback表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续进行,系统将