zoukankan      html  css  js  c++  java
  • SpringSecurity的Filter执行顺序在源码中的体现

    在网上看各种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 = 100;
        private Map<String, Integer> filterToOrder = new HashMap<String, Integer>();
    
        FilterComparator() {
            int order = 100;
            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 + 1);
        }
    
        /**
         * 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 - 1);
        }
    
        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

  • 相关阅读:
    .net序列化和反序列化(一)——自动序列化
    在Sql Server 2005使用公用表表达式CTE简化复杂的查询语句
    使用JQuery与iframe交互
    FCKeditor自定义工具栏和定义多个工具栏
    FCKeditor自定义非空验证
    PHP5.3.6的IIS配置
    Linux下缓存服务器的应用
    PHP采集程序中常用的函数
    关于PHP5.3.x和Zend Optimizer(Zend Guard Loader),以及shopex4.8.5安装的问题
    SQLserver数据库还原出现错误112(磁盘空间不足)的解决办法
  • 原文地址:https://www.cnblogs.com/zsxneil/p/6616616.html
Copyright © 2011-2022 走看看