美文网首页spring bootspring cloud 微服务
spring cloud OAuth2资源服务器的过滤器链路浅析

spring cloud OAuth2资源服务器的过滤器链路浅析

作者: 大浪滔滔 | 来源:发表于2018-01-29 23:46 被阅读1248次

    1. 导语

    在Spring cloud体系中设计OAuth2应用时,当我们使用@EnableResourceServer注解把某个spring boot应用声明为一个OAuth2的资源服务器时,spring cloud将会创建一系列的web安全过滤器链。

    接下来,我将带大家一起将分析spring cloud的源码,分析过滤器链路的工作原理。

    2. spring cloud的web安全配置

    spring boot启动时,在WebSecurityConfiguration中加载所有的web安全配置,并根据Order进行排序:

    package org.springframework.security.config.annotation.web.configuration;
    
    @Configuration
    public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
    
        // 注意:webSecurityConfigurers参数通过注解的方式注入
        @Autowired(required = false)
        public void setFilterChainProxySecurityConfigurer(
                ObjectPostProcessor<Object> objectPostProcessor,
                @Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)
                throws Exception {
            webSecurity = objectPostProcessor
                    .postProcess(new WebSecurity(objectPostProcessor));
            if (debugEnabled != null) {
                webSecurity.debug(debugEnabled);
            }
    
            // 根据@Order顺序进行排序
            Collections.sort(webSecurityConfigurers, AnnotationAwareOrderComparator.INSTANCE);
    
            Integer previousOrder = null;
            Object previousConfig = null;
            for (SecurityConfigurer<Filter, WebSecurity> config : webSecurityConfigurers) {
                Integer order = AnnotationAwareOrderComparator.lookupOrder(config);
                if (previousOrder != null && previousOrder.equals(order)) {
                    throw new IllegalStateException(
                            "@Order on WebSecurityConfigurers must be unique. Order of "
                                    + order + " was already used on " + previousConfig + ", so it cannot be used on "
                                    + config + " too.");
                }
                previousOrder = order;
                previousConfig = config;
            }
            for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
                webSecurity.apply(webSecurityConfigurer);
            }
            this.webSecurityConfigurers = webSecurityConfigurers;
        }
    
    }
    

    注意:webSecurityConfigurers参数通过注解的方式注入:

    @Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers
    

    即在spring容器里查找autowiredWebSecurityConfigurersIgnoreParents的实例并调用其getWebSecurityConfigurer()方法。

    AutowiredWebSecurityConfigurersIgnoreParents类的作用是从spring容器中找到WebSecurityConfigure接口的所有实例:

    final class AutowiredWebSecurityConfigurersIgnoreParents {
    
        private final ConfigurableListableBeanFactory beanFactory;
    
        public AutowiredWebSecurityConfigurersIgnoreParents(
                ConfigurableListableBeanFactory beanFactory) {
            Assert.notNull(beanFactory, "beanFactory cannot be null");
            this.beanFactory = beanFactory;
        }
    
        // 从spring容器中找到WebSecurityConfigurer接口的所有实例
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public List<SecurityConfigurer<Filter, WebSecurity>> getWebSecurityConfigurers() {
            List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers = new ArrayList<SecurityConfigurer<Filter, WebSecurity>>();
            Map<String, WebSecurityConfigurer> beansOfType = beanFactory
                    .getBeansOfType(WebSecurityConfigurer.class);
            for (Entry<String, WebSecurityConfigurer> entry : beansOfType.entrySet()) {
                webSecurityConfigurers.add(entry.getValue());
            }
            return webSecurityConfigurers;
        }
    }
    

    找到的实例包括:

    顺序 (Order) 说明
    IgnoredPathsWebSecurityConfigurerAdapter -2147483648:Ordered.HIGHEST_PRECEDENCE 白名单
    ManagementWebSecurityConfigurerAdapter 2147483637:Ordered.LOWEST_PRECEDENCE - 10 spring自身的管理/监控端点过滤器链
    ResourceServerConfiguration 2147483639:Ordered.LOWEST_PRECEDENCE - 8 资源服务器相关的过滤器链
    ApplicationWebSecurityConfigurerAdapter 2147483642:Ordered.LOWEST_PRECEDENCE - 5 默认的web安全过滤器链

    其中:
    ResourceServerConfiguration的Order默认为3,但在OAuth2的资源服务器中,运行时将会被覆盖为其他值,具体值在ResourceServerProperties类的属性filterOrder中定义:

    @ConfigurationProperties(prefix = "security.oauth2.resource")
    public class ResourceServerProperties implements Validator, BeanFactoryAware {
    
        /**
         * The order of the filter chain used to authenticate tokens. Default puts it after
         * the actuator endpoints and before the default HTTP basic filter chain (catchall).
         */
        private int filterOrder = SecurityProperties.ACCESS_OVERRIDE_ORDER - 1;
    

    3. 安全配置的初始化

    接下来,在AbstractConfiguredSecurityBuilder类中对安全配置类进行初始化:

    package org.springframework.security.config.annotation;
    
    public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
            extends AbstractSecurityBuilder<O> {
    
        private void init() throws Exception {
            // configurers里面初始化了4个配置
            Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();
    
            for (SecurityConfigurer<O, B> configurer : configurers) {
                configurer.init((B) this);
            }
    
            for (SecurityConfigurer<O, B> configurer : configurersAddedInInitializing) {
                configurer.init((B) this);
            }
        }
    }
    

    configurers里面包含以下4个web安全配置类,即上面在spring容器中查找到的4个安全配置类实例:

    [0] SpringBootWebSecurityConfiguration$IgnoredPathsWebSecurityConfigurerAdapter  (id=7391)  
    [1] ManagementWebSecurityAutoConfiguration$ManagementWebSecurityConfigurerAdapter$$EnhancerBySpringCGLIB$$b7d4741a  (id=105)    
    [2] ResourceServerConfiguration$$EnhancerBySpringCGLIB$$dae34c39  (id=7392) 
    [3] SpringBootWebSecurityConfiguration$ApplicationWebSecurityConfigurerAdapter$$EnhancerBySpringCGLIB$$39896683  (id=7393)
    

    ResourceServerConfiguration的配置

    package org.springframework.security.oauth2.config.annotation.web.configuration;
    
    @Configuration
    public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter implements Ordered {
      
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            ResourceServerSecurityConfigurer resources = new ResourceServerSecurityConfigurer();
            ResourceServerTokenServices services = resolveTokenServices();
            if (services != null) {
                resources.tokenServices(services);
            }
            else {
                if (tokenStore != null) {
                    resources.tokenStore(tokenStore);
                }
                else if (endpoints != null) {
                    resources.tokenStore(endpoints.getEndpointsConfigurer().getTokenStore());
                }
            }
            if (eventPublisher != null) {
                resources.eventPublisher(eventPublisher);
            }
            for (ResourceServerConfigurer configurer : configurers) {
                configurer.configure(resources);
            }
            // @formatter:off
            http.authenticationProvider(new AnonymousAuthenticationProvider("default"))
            // N.B. exceptionHandling is duplicated in resources.configure() so that
            // it works
            .exceptionHandling()
                    .accessDeniedHandler(resources.getAccessDeniedHandler()).and()
                    .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                    .csrf().disable();
            // @formatter:on
            http.apply(resources);
            if (endpoints != null) {
                // Assume we are in an Authorization Server
                http.requestMatcher(new NotOAuthRequestMatcher(endpoints.oauth2EndpointHandlerMapping()));
            }
            for (ResourceServerConfigurer configurer : configurers) {
                // Delegates can add authorizeRequests() here
                configurer.configure(http);
            }
            if (configurers.isEmpty()) {
                // Add anyRequest() last as a fall back. Spring Security would
                // replace an existing anyRequest() matcher with this one, so to
                // avoid that we only add it if the user hasn't configured anything.
                http.authorizeRequests().anyRequest().authenticated();
            }
        }
    }
    

    4. 将安全配置类转化为安全过滤器链

    将安全配置类转化为安全过滤器链的这个工作是由WebSecurity类来完成的,我们来看下相关代码:

    package org.springframework.security.config.annotation.web.builders;
    public final class WebSecurity extends
            AbstractConfiguredSecurityBuilder<Filter, WebSecurity> implements
            SecurityBuilder<Filter>, ApplicationContextAware {
        @Override
        protected Filter performBuild() throws Exception {
            Assert.state(
                    !securityFilterChainBuilders.isEmpty(),
                    "At least one SecurityBuilder<? extends SecurityFilterChain> needs to be specified. Typically this done by adding a @Configuration that extends WebSecurityConfigurerAdapter. More advanced users can invoke "
                            + WebSecurity.class.getSimpleName()
                            + ".addSecurityFilterChainBuilder directly");
            int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
            List<SecurityFilterChain> securityFilterChains = new ArrayList<SecurityFilterChain>(
                    chainSize);
            // 一、针对白名单url创建一条空的过滤器链(Chain A)
            for (RequestMatcher ignoredRequest : ignoredRequests) {
                securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
            }
            // 二、安全相关的过滤器链,可能为多条,这里是3条。
            for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
                securityFilterChains.add(securityFilterChainBuilder.build());
            }
            FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
            if (httpFirewall != null) {
                filterChainProxy.setFirewall(httpFirewall);
            }
            filterChainProxy.afterPropertiesSet();
    
            Filter result = filterChainProxy;
            if (debugEnabled) {
                logger.warn("\n\n"
                        + "********************************************************************\n"
                        + "**********        Security debugging is enabled.       *************\n"
                        + "**********    This may include sensitive information.  *************\n"
                        + "**********      Do not use in a production system!     *************\n"
                        + "********************************************************************\n\n");
                result = new DebugFilter(filterChainProxy);
            }
            postBuildAction.run();
            return result;
        }
    

    在上面的代码中,spring cloud一共创建了4条过滤器链。

    其中:

    4.1 Chain A:配置了一个静态文件url的白名单

    对应着前面的白名单安全配置类IgnoredPathsWebSecurityConfigurerAdapter

    具体的配置在:

    package org.springframework.boot.autoconfigure.security;
    public class SpringBootWebSecurityConfiguration {
        private static List<String> DEFAULT_IGNORED = Arrays.asList("/css/**", "/js/**",
                "/images/**", "/webjars/**", "/**/favicon.ico");
        // ...
    
        private class DefaultIgnoredRequestCustomizer implements IgnoredRequestCustomizer {
    
            // 这里定义了一个魔法
            private List<String> getIgnored(SecurityProperties security) {
                List<String> ignored = new ArrayList<String>(security.getIgnored());
                if (ignored.isEmpty()) {
                    ignored.addAll(DEFAULT_IGNORED);
                }
                else if (ignored.contains("none")) {
                    ignored.remove("none");
                }
                return ignored;
            }
        }
    }
    

    我们可以看到SpringBootWebSecurityConfiguration定义了一个默认的uri白名单,里面定义了一些静态文件的uri:

    • "/css/**"
    • "/js/**",
    • "/images/**"
    • "/webjars/**"
    • "/**/favicon.ico"

    因此,对匹配这些uri的http请求,将会跳过后续所有的过滤器链。
    那么,接下来,我们可能会有疑问,如果我想对这些uri进行定制化怎么办?
    答案就在getIgnored()方法,它定义了一个魔法,因此允许我们对白名单进行定制化。有两种方法:
    1、在application.yml中配置security.ignored属性

    security: 
      ignored: none
    

    如果security.ignored=none,则忽略上面的白名单。
    当然,你也可以做个性化的配置,如:

    security: 
      ignored: /css/**,/js/**,/images/**,/webjars/**,/**/favicon.ico,/static/**
    

    2、或者通过代码实现

    @Component
    public class CustomSecurityProperties extends SecurityProperties {
        public CustomSecurityProperties() {
            // the default list is empty
            List<String> ignoredPaths = getIgnored();
            ignoredPaths.add("none");
        }
    }
    

    4.2 安全相关的过滤器链,这里创建了3条

    对应前面的其他3个过滤器安全配置类:

    • ManagementWebSecurityConfigurerAdapter,spring自身的管理/监控端点过滤器链
    • ResourceServerConfiguration,资源服务器相关的过滤器链
    • ApplicationWebSecurityConfigurerAdapter,默认的web安全过滤器链

    1. ManagementWebSecurityConfigurerAdapter

    ManagementWebSecurityConfigurerAdapter是spring自身的管理/监控端点过滤器链。包括以下端点:

    OrRequestMatcher 
        [requestMatchers=
            [
                Ant [pattern='/pause'], 
                Ant [pattern='/pause/**'], 
                Ant [pattern='/pause.*'], 
                Ant [pattern='/pause/'], 
                Ant [pattern='/env'], 
                Ant [pattern='/env/**'], 
                Ant [pattern='/env.*'], 
                Ant [pattern='/env/'], 
                Ant [pattern='/features'], 
                Ant [pattern='/features/**'], 
                Ant [pattern='/features.*'], 
                Ant [pattern='/features/'], 
                Ant [pattern='/loggers'], 
                Ant [pattern='/loggers/**'], 
                Ant [pattern='/loggers.*'], 
                Ant [pattern='/loggers/'], 
                Ant [pattern='/archaius'], 
                Ant [pattern='/archaius/**'], 
                Ant [pattern='/archaius.*'], 
                Ant [pattern='/archaius/'], 
                Ant [pattern='/autoconfig'], 
                Ant [pattern='/autoconfig/**'], 
                Ant [pattern='/autoconfig.*'], 
                Ant [pattern='/autoconfig/'], 
                Ant [pattern='/mappings'], 
                Ant [pattern='/mappings/**'], 
                Ant [pattern='/mappings.*'], 
                Ant [pattern='/mappings/'], 
                Ant [pattern='/refresh'], 
                Ant [pattern='/refresh/**'], 
                Ant [pattern='/refresh.*'], 
                Ant [pattern='/refresh/'], 
                Ant [pattern='/restart'], 
                Ant [pattern='/restart/**'], 
                Ant [pattern='/restart.*'], 
                Ant [pattern='/restart/'], 
                Ant [pattern='/info'], 
                Ant [pattern='/info/**'], 
                Ant [pattern='/info.*'], 
                Ant [pattern='/info/'], 
                Ant [pattern='/resume'], 
                Ant [pattern='/resume/**'], 
                Ant [pattern='/resume.*'], 
                Ant [pattern='/resume/'], 
                Ant [pattern='/metrics'], 
                Ant [pattern='/metrics/**'], 
                Ant [pattern='/metrics.*'], 
                Ant [pattern='/metrics/'], 
                Ant [pattern='/beans'], 
                Ant [pattern='/beans/**'], 
                Ant [pattern='/beans.*'], 
                Ant [pattern='/beans/'], 
                Ant [pattern='/trace'], 
                Ant [pattern='/trace/**'], 
                Ant [pattern='/trace.*'], 
                Ant [pattern='/trace/'], 
                Ant [pattern='/auditevents'], 
                Ant [pattern='/auditevents/**'], 
                Ant [pattern='/auditevents.*'], 
                Ant [pattern='/auditevents/'], 
                Ant [pattern='/configprops'], 
                Ant [pattern='/configprops/**'], 
                Ant [pattern='/configprops.*'], 
                Ant [pattern='/configprops/'], 
                Ant [pattern='/service-registry'], 
                Ant [pattern='/service-registry/**'], 
                Ant [pattern='/service-registry.*'], 
                Ant [pattern='/service-registry/'], 
                Ant [pattern='/dump'], 
                Ant [pattern='/dump/**'], 
                Ant [pattern='/dump.*'], 
                Ant [pattern='/dump/'], 
                Ant [pattern='/health'], 
                Ant [pattern='/health/**'], 
                Ant [pattern='/health.*'], 
                Ant [pattern='/health/'], 
                Ant [pattern='/heapdump'], 
                Ant [pattern='/heapdump/**'], 
                Ant [pattern='/heapdump.*'], 
                Ant [pattern='/heapdump/']
            ]
        ]
    

    2. ResourceServerConfiguration

    ResourceServerConfiguration对应着我们自定义的资源服务器的配置类,我们可以在里面配置我们自定义的过滤器。例如:

    /**
     * 自定义资源服务器配置
     * 
     * @author 大浪滔滔
     *
     */
    @Configuration
    @EnableConfigurationProperties(SecuritySettings.class)
    public class DefaultResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    
        @Override
        public void configure(final HttpSecurity http) throws Exception {
            // 自定义的过滤器
            http.addFilterBefore(threadLocalFilter(), WebAsyncManagerIntegrationFilter.class);
            http.addFilterAfter(accessFilter(), ThreadLocalFilter.class);
            http.addFilterAfter(serviceAuthFilter, ThreadLocalFilter.class);
          
            // ...
        }
    }
    

    在这个过滤器链中包含以下过滤器:

    序号 过滤器
    [0] ThreadLocalFilter (id=382),安全上下文过滤器。
    [1] WebAsyncManagerIntegrationFilter (id=383)
    [2] AccessFilter (id=384),日志过滤器。
    [3] ServiceAuthFilter (id=385),微服务token认证过滤器。
    [4] SecurityContextPersistenceFilter (id=387)
    [5] HeaderWriterFilter (id=388)
    [6] LogoutFilter (id=389)
    [7] OAuth2AuthenticationProcessingFilter (id=390)
    [8] RequestCacheAwareFilter (id=391)
    [9] SecurityContextHolderAwareRequestFilter (id=392)
    [10] AnonymousAuthenticationFilter (id=393)
    [11] SessionManagementFilter (id=394)
    [12] ExceptionTranslationFilter (id=395)
    [13] FilterSecurityInterceptor (id=396)

    其中,ThreadLocalFilter、AccessFilter和ServiceAuthFilter是我们自定义的过滤器。

    其他过滤器是spring自动生成的,见以下代码:

    package org.springframework.security.config.annotation.web.configuration;
    
    @Order(100)
    public abstract class WebSecurityConfigurerAdapter implements
            WebSecurityConfigurer<WebSecurity> {
      
        protected final HttpSecurity getHttp() throws Exception {
            if (http != null) {
                return http;
            }
    
            DefaultAuthenticationEventPublisher eventPublisher = objectPostProcessor
                    .postProcess(new DefaultAuthenticationEventPublisher());
            localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);
    
            AuthenticationManager authenticationManager = authenticationManager();
            authenticationBuilder.parentAuthenticationManager(authenticationManager);
            Map<Class<? extends Object>, Object> sharedObjects = createSharedObjects();
    
            http = new HttpSecurity(objectPostProcessor, authenticationBuilder,
                    sharedObjects);
            if (!disableDefaults) {
                // @formatter:off
                http
                    .csrf().and() // 
                    .addFilter(new WebAsyncManagerIntegrationFilter())
                    .exceptionHandling().and()
                    .headers().and()
                    .sessionManagement().and()
                    .securityContext().and()
                    .requestCache().and()
                    .anonymous().and()
                    .servletApi().and()
                    .apply(new DefaultLoginPageConfigurer<HttpSecurity>()).and()
                    .logout();
                // @formatter:on
                ClassLoader classLoader = this.context.getClassLoader();
                List<AbstractHttpConfigurer> defaultHttpConfigurers =
                        SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);
    
                for(AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
                    http.apply(configurer);
                }
            }
            configure(http);
            return http;
        }
    }
    

    3. ApplicationWebSecurityConfigurerAdapter

    ApplicationWebSecurityConfigurerAdapter是spring默认的web安全过滤器链,它对uri的匹配规则是

    OrRequestMatcher [requestMatchers=[Ant [pattern='/**']]]
    

    即匹配所有的http请求。

    它包括以下过滤器:

    序号 过滤器
    [0] WebAsyncManagerIntegrationFilter (id=370)
    [1] SecurityContextPersistenceFilter (id=371)
    [2] HeaderWriterFilter (id=372)
    [3] LogoutFilter (id=373)
    [4] BasicAuthenticationFilter (id=374)
    [5] RequestCacheAwareFilter (id=375)
    [6] SecurityContextHolderAwareRequestFilter (id=376)
    [7] AnonymousAuthenticationFilter (id=377)
    [8] SessionManagementFilter (id=378)
    [9] ExceptionTranslationFilter (id=379)
    [10] FilterSecurityInterceptor (id=380)

    5. 过滤器链的选择

    在前面的分析中,spring创建了4条过滤器链,那么,是否每条链都会被执行呢?

    答案是否定的,这4条过滤器链每条都有uri的匹配规则,spring将会根据http请求的uri按顺序去匹配,第1条符合条件的过滤器链将会被选中并执行。

    相关的代码如下:

    package org.springframework.security.web;
    
    public class FilterChainProxy extends GenericFilterBean {
      
        /**
         * Returns the first filter chain matching the supplied URL.
         *
         * @param request the request to match
         * @return an ordered array of Filters defining the filter chain
         */
        private List<Filter> getFilters(HttpServletRequest request) {
            for (SecurityFilterChain chain : filterChains) {
                if (chain.matches(request)) {
                    return chain.getFilters();
                }
            }
    
            return null;
        }
    

    6. 过滤器的执行顺序

    HttpSecurity类定义了一个安全过滤器排序器FilterComparator

    package org.springframework.security.config.annotation.web.builders;
    
    public final class HttpSecurity extends
            AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
            implements SecurityBuilder<DefaultSecurityFilterChain>,
            HttpSecurityBuilder<HttpSecurity> {
              
        // 过滤器排序器
        private FilterComparator comparator = new FilterComparator();
              
    }          
    

    FilterComparator类定义一些spring自带过滤器的默认顺序:

    package org.springframework.security.config.annotation.web.builders;
    
    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(CorsFilter.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);
        }
    }
    
    过滤器名称 过滤器类 顺序 Order值 说明
    MetricsFilter @Order(Ordered.HIGHEST_PRECEDENCE) -2147483648
    OrderedCharacterEncodingFilter -2147483648
    OrderedHiddenHttpMethodFilter -10000
    OrderedHttpPutFormContentFilter -9900
    OrderedRequestContextFilter -105
    ThreadLocalFilter -104 自定义过滤器
    ServiceAuthFilter -103 自定义过滤器
    AccessFilter -102 自定义过滤器
    springSecurityFilterChain DelegatingFilterProxyRegistrationBean -100
    webRequestLoggingFilter WebRequestTraceFilter 2147483637

    相关文章

      网友评论

        本文标题:spring cloud OAuth2资源服务器的过滤器链路浅析

        本文链接:https://www.haomeiwen.com/subject/ehbaaxtx.html