报错:Cannot register after unregis

2019-05-15  本文已影响0人  晨暮时代

因为对springsecurity不熟悉,在配置过滤器的时候报出了如题所示的错误,对应的代码如下:

    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable() 
        .exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
     .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
     .and().authorizeRequests()
     .antMatchers("/login", "/project", "/fund").permitAll()
     .anyRequest().authenticated()
     // 产生错误的代码
     .and().addFilterBefore(new JwtLoginFilter(jwtUserDetailService, jwtTokenUtil), OncePerRequestFilter.class);
        http.headers().frameOptions().sameOrigin()
                .cacheControl();
    }

错就错在addFilterBefore那里,我不应该用OncePerRequestFilter.class作为第二个参数。点进addFilterBefore查看内部源码:

 public HttpSecurity addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter) {
        this.comparator.registerBefore(filter.getClass(), beforeFilter);
        return this.addFilter(filter);
    }

再看registerBefore的源码:

public void registerBefore(Class<? extends Filter> filter, Class<? extends Filter> beforeFilter) {
        Integer position = this.getOrder(beforeFilter);
        if (position == null) {
            throw new IllegalArgumentException("Cannot register after unregistered Filter " + beforeFilter);
        } else {
            this.put(filter, position - 1);
        }
    }

发现报错原因是由于position == null。再点getOrder进去看看:

private Integer getOrder(Class<?> clazz) {
    while(clazz != null) {
        // 查找XXXFilter.class所在的位置
        Integer result = (Integer)this.filterToOrder.get(clazz.getName());
        if (result != null) {
            return result;
        }

        clazz = clazz.getSuperclass();
    }

    return null;
}

可以看到,filterToOrder是一个Map,其预先put了固定的若干个过滤器类,它会试图去查找XXXFilter.class,但是没有找到,所以为null。addFilterBefore的作用就是将我们自定义的过滤器根据XXXFilter.class所在filterToOrder中的位置,是插在它的前面还是它的后面。

上一篇下一篇

猜你喜欢

热点阅读