• 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 />命名空间配置选项可以处理绝大部分应用场景。示例如下:

      <http auto-config="true">
        <remember-me key="xxx" token-validity-seconds="xxx" data-source-ref="dataSource"/>
        <form-login login-page="/login.jsp"/>
        <logout logout-success-url="/login.jsp"/>
        <intercept-url pattern="/*" access="ROLE_USER"/>
      </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架构层次

     

     6. 默认filter的创建

  • 相关阅读:
    智算之道复赛
    试题 历届试题 幸运数(模拟)
    使用memcpy函数时要注意拷贝数据的长度
    试题 历届试题 大臣的旅费(求树的直径,两次dfs)
    试题 历届试题 连号区间数(规律)
    试题 历届试题 错误票据(输入处理,桶排序)
    试题 历届试题 剪格子(dfs)
    Rope大法(可持久化平衡树)
    常用数论知识总结(持续更新)
    计蒜客 035 三角形内点的个数(皮克定理)
  • 原文地址:https://www.cnblogs.com/davidwang456/p/4521955.html
Copyright © 2020-2023  润新知