即使模式不匹配,过滤器也会执行,Spring Security

问题描述

我正在使用的当前安全配置:

@Configuration
public class SecurityConfig {

/**
 * Default order of 3 as per Spring documentation.
 */
@Configuration
@EnableWebSecurity
@EnableResourceServer
public static class OAuth2SecurityConfiguration extends ResourceServerConfigurerAdapter {
    private final TokenStore tokenStore;

    @Autowired
    public OAuth2SecurityConfiguration(TokenStore tokenStore) {
        this.tokenStore = tokenStore;
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.tokenStore(tokenStore);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.apply(CommonSecurityConfiguration
                .commonSecurityConfiguration())
            .and()
                .authorizeRequests().anyRequest()
                .authenticated();
    }

}

@Configuration
@Order(1)
public static class SecretAuthSecurityConfiguration extends WebSecurityConfigurerAdapter {

    private JPAAuthenticationProvider authenticationProvider;

    @Autowired
    public void setAuthenticationProvider(JPAAuthenticationProvider authenticationProvider) {
        this.authenticationProvider = authenticationProvider;
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider);
    }

    @Bean
    public FilterRegistrationBean<Filter> secretFilterRegistrationBean() {
        var filterRegistrationBean =
                new FilterRegistrationBean<>();

        filterRegistrationBean.setFilter(
                new SecretFilter();
        return filterRegistrationBean;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .requestMatchers()
                .antMatchers("/resource1/api/**","/resource2/api/**")
            .and()
                .addFilterafter(this.secretFilterRegistrationBean().getFilter(),logoutFilter.class)
            .apply(CommonSecurityConfiguration
                    .commonSecurityConfiguration());
    }

}

public static class CommonSecurityConfiguration
        extends AbstractHttpConfigurer<CommonSecurityConfiguration,HttpSecurity> {

    @Override
    public void init(HttpSecurity http) throws Exception {
        http
                .cors()
            .and()
                .csrf()
                .disable();
    }

    public static CommonSecurityConfiguration commonSecurityConfiguration() {
        return new CommonSecurityConfiguration();
    }

}

}

我是Spring Security的新手,我的目标是构建一个应用程序,该应用程序允许对应用程序中的不同路径进行不同类型的身份验证。

据我从文章和Spring文档中了解到的那样,在使用ANT匹配器之类的东西来管理过滤器链时,您具有很大的灵活性。

在上面的代码段中,我尝试配置2个过滤器链-每个过滤器链对应一种身份验证类型:

  1. OAuth2,基于令牌的安全性配置-在静态类OAuth2SecurityConfiguration中进行了描述-我在其中使用了注释@EnableResourceServer,该注释会自动org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter添加到新的过滤器链中。根据有关@EnableResourceServer的Spring文档:

该注释会创建一个WebSecurityConfigurerAdapter,其硬编码顺序(为3)。

  1. 自定义身份验证类型,它基于自定义过滤器。这个过滤器做什么?它检查传入请求中的标头,并验证该标头中是否存在受信任的秘密,没有什么特别的。这是过滤器的核心:
public class SecretFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,FilterChain filterChain)
                                    throws IOException,servletexception {

        log.info("Inside SecretFilter.");

        String secret = this.resolveSecret(httpServletRequest);
        if (secret.isValid()) {
                SecurityContextHolder.getContext().setAuthentication(
                        new UsernamePasswordAuthenticationToken(null,null,null));
        }

        filterChain.doFilter(httpServletRequest,httpServletResponse);

        /**
         * Clearing the security context after the request is made.
         */
        SecurityContextHolder.getContext().setAuthentication(null);
}

生成的过滤器链:

o.s.s.web.DefaultSecurityFilterChain: Creating filter chain:a OrRequestMatcher [requestMatchers=[Ant [pattern='/resource1/api/star.star'],Ant [pattern='/resource2/api/star.star']]]
 - WebAsyncManagerIntegrationFilter
 - SecurityContextPersistenceFilter
 - HeaderWriterFilter
 - CorsFilter
 - logoutFilter
 - SecretFilter     <------- here is my filter
 - RequestCacheAwareFilter
 - SecurityContextHolderAwareRequestFilter
 - AnonymousAuthenticationFilter
 - SessionManagementFilter
 - ExceptionTranslationFilter
o.s.s.web.DefaultSecurityFilterChain: Creating filter chain: org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration$NotOAuthRequestMatcher
 - WebAsyncManagerIntegrationFilter
 - SecurityContextPersistenceFilter
 - HeaderWriterFilter
 - CorsFilter
 - logoutFilter
 - OAuth2AuthenticationProcessingFilter
 - RequestCacheAwareFilter
 - SecurityContextHolderAwareRequestFilter
 - AnonymousAuthenticationFilter
 - SessionManagementFilter
 - ExceptionTranslationFilter
 - FilterSecurityInterceptor

应该处理这种身份验证的静态配置类已用@Order(1)注释标记,因为我希望请求首先通过带有自定义过滤器的过滤器链传递,否则,如果请求不是针对指定的路径,例如/resource1/api/**,然后通过OAuth过滤器链。

例如,当我对路径/resource1/api/X进行常规请求时,一切进展顺利,并且过滤器链得到执行。但是,当收到除上述指定路径以外的其他路径上的请求时,控制台将向我显示以下内容

2020-09-22 01:00:03.698 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-09-22 01:00:03.698 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-09-22 01:00:03.698 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-09-22 01:00:03.698 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 4 of 12 in additional filter chain; firing Filter: 'CorsFilter'
2020-09-22 01:00:03.703 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 5 of 12 in additional filter chain; firing Filter: 'logoutFilter'
2020-09-22 01:00:03.703 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 6 of 12 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
2020-09-22 01:00:03.715 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2020-09-22 01:00:03.715 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2020-09-22 01:00:03.715 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2020-09-22 01:00:03.715 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2020-09-22 01:00:03.715 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2020-09-22 01:00:03.716 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2020-09-22 01:00:03.717 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : /profile/?date=2020-09-21T22:00:03Z reached end of additional filter chain; proceeding with original chain
2020-09-22 01:00:03.718  INFO 928 --- [nio-8080-exec-4] c.s.p.s.filters.SecretFilter             : Inside SecretFilter.

为什么SecretFilter在OAuth过滤器链的末尾执行?它没有使用@Order注释或其他任何注释。我的路径不应该匹配,因此包含过滤器的过滤器链不应该被触发。看起来很清楚,但这是我无法获得的小东西。

我的直觉是,过滤器以认的Ordered.LOWEST_PRECEDENCE顺序注册并以某种方式放置,并且在FilterChainProxy完成当前多路复用链的工作后执行

任何帮助或参考,以了解更多有关它的信息。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...