【问题标题】:Spring boot security - two distinct filtersSpring Boot 安全性 - 两个不同的过滤器
【发布时间】:2017-02-03 14:19:27
【问题描述】:

我正在尝试使用两个不同的过滤器配置 Spring Security。 我想要的是有一些将由一个过滤器处理的 URL,以及一些将由其他过滤器处理的 URL。 这是我想出的设置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled=true)
public class SecurityConfigurationContext {

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

        @Override
        protected void configure(final HttpSecurity http) throws Exception {
            // Handlers and entry points
            http.exceptionHandling()
                .authenticationEntryPoint(MyCustomAuthenticationEntryPoint);


            http.authorizeRequests()
                .antMatchers(HttpMethod.GET, "/filter1-urls/*").hasRole("USER");


            http.addFilterBefore(myCustomFilter1, ChannelProcessingFilter.class);

            http.csrf().disable();
            http.httpBasic()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(myCustomAuthenticationService)
                .passwordEncoder(new BCryptPasswordEncoder());
        }
    }

    @Order(2)
    @Configuration
    public static class ConfigurerAdapter2 extends WebSecurityConfigurerAdapter{
        ...

        @Override
        protected void configure(final HttpSecurity http) throws Exception {
            // Handlers and entry points
            http.exceptionHandling()
                .authenticationEntryPoint(MyCustomAuthenticationEntryPoint);


            http.authorizeRequests()
                .antMatchers(HttpMethod.GET, "/filter2-urls/*").hasRole("SUPER_USER");


            http.addFilterBefore(myCustomFilter2, ChannelProcessingFilter.class);

            http.csrf().disable();
            http.httpBasic()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(myCustomAuthenticationService)
                .passwordEncoder(new BCryptPasswordEncoder());
        }
    }
}

过滤器看起来像这样:

过滤器1:

@Component
@Order(1)
public final class MyCustomFilter1 implements Filter{

    public MyCustomFilter1() {
        super();
    }

    @Override
    public final void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException {
        // logic for processing filter1-urls
    }
}

过滤器2:

@Component
@Order(2)
public final class MyCustomFilter2 implements Filter{

    public MyCustomFilter2() {
        super();
    }

    @Override
    public final void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException {
        // logic for processing filter2-urls
    }
}

问题在于,对于每个请求,这两个过滤器都在一个链中调用。我提出的任何请求,它首先通过一个过滤器,然后通过另一个,而不是只通过一个。

我该如何解决这个问题?

提前致谢。

【问题讨论】:

    标签: java spring filtering


    【解决方案1】:

    你应该只有一个ConfigurerAdapter。您可以将其组合成一个配置:

    http.exceptionHandling()
                .authenticationEntryPoint(MyCustomAuthenticationEntryPoint);
    http
         .authorizeRequests()
         .antMatchers(HttpMethod.GET, "/filter1-urls/*").hasRole("USER")
         .antMatchers(HttpMethod.GET, "/filter2-urls/*").hasRole("SUPER_USER");
    http.addFilterBefore(myCustomFilter, ChannelProcessingFilter.class);
    

    将调用这两个过滤器,因为您设置了此类行为。你应该只留下一个过滤器来达到你想要的结果。

    @Component
    public final class MyCustomFilter implements Filter {
    
        public MyCustomFilter() {
            super();
        }
    
        @Override
        public final void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException {
        // logic for processing filter2-urls and filter1-urls
        }
     }
    

    无论如何,您的过滤器都会被链式调用。如果你想拆分你的过滤器,你应该在你的过滤器中添加if语句来过滤只需要的url(你可以从ServletRequest获取请求url

    @Component
    public final class MyCustomFilter2 implements Filter {
    
        public MyCustomFilter2() {
            super();
        }
    
        @Override
        public final void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException {
            if (/*is filter2 urls*/) {
            // logic for processing filter2-urls
            }
        }
     }
    

    【讨论】:

    • 嗯。谢谢。我会试一试,如果我成功了,请告诉你。
    猜你喜欢
    • 1970-01-01
    • 2022-08-16
    • 2017-03-13
    • 2020-01-03
    • 2022-08-05
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    相关资源
    最近更新 更多