报错: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中的位置,是插在它的前面还是它的后面。