美文网首页Spring Security
解决spring security自定义filter重复执行问题

解决spring security自定义filter重复执行问题

作者: go4it | 来源:发表于2017-11-27 10:23 被阅读1748次

    本文讲一个spring security自定义filter非常容易出现的一个问题,那就是filter被执行两遍。

    复现

    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Bean
        public DemoFilter demoFilter(){
            return new DemoFilter();
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .addFilterBefore(demoFilter(),AnonymousAuthenticationFilter.class)
                    .authorizeRequests()
                    .antMatchers("/login","/css/**", "/js/**","/fonts/**").permitAll()
                    .anyRequest().authenticated();
        }
    }
    

    其中DemoFilter如下

    public class DemoFilter extends GenericFilterBean {
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            //do something
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
    

    原因

    在spring容器托管的GenericFilterBean的bean,都会自动加入到servlet的filter chain,而上面的定义,还额外把filter加入到了spring security的
    AnonymousAuthenticationFilter之前。而spring security也是一系列的filter,在mvc的filter之前执行。因此在鉴权通过的情况下,就会先后各执行一次。

    解决方案

    方案1

    不把filter托管给spring,直接new,比如

    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .addFilterBefore(new DemoFilter(),AnonymousAuthenticationFilter.class)
                    .authorizeRequests()
                    .antMatchers("/login","/css/**", "/js/**","/fonts/**").permitAll()
                    .anyRequest().authenticated();
        }
    }
    

    方案2

    有时候filter需要访问spring容器的资源,托管给容器可能好些,那么这个时候,就可以像FilterSecurityInterceptor做个标记FILTER_APPLIED

    public class DemoFilter extends GenericFilterBean {
    
        private static final String FILTER_APPLIED = "__spring_security_demoFilter_filterApplied";
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            if (servletRequest.getAttribute(FILTER_APPLIED) != null) {
                filterChain.doFilter(servletRequest, servletResponse);
                return ;
            }
            //do something
            servletRequest.setAttribute(FILTER_APPLIED,true);
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
    

    doc

    相关文章

      网友评论

        本文标题:解决spring security自定义filter重复执行问题

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