现象:
利用shiro进行过滤链对路径拦截或者放行,从放行顺序和拦截路径规则都没有错误,但是出现已经放行的路径调用了自定义的拦截器,导致全站路径拦截。
错误示例
错误实例代码
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
//拦截器filter
HashMap<String, Filter> requestFilterMap = new HashMap<>();
requestFilterMap.put("jwt", new jwtFilter()); //第一种写法
requestFilterMap.put("jwt", getJwtFilter()); //第二种写法
factoryBean.setFilters(requestFilterMap);
//自定义过滤器
Map<String, String> filterMap = new HashMap<>();
// 访问401和404页面不通过我们的Filter
filterMap.put("/user/login", "anon");
filterMap.put("/user/register", "anon");
filterMap.put("/doc.html", "anon");
filterMap.put("/swagger-resources", "anon");
filterMap.put("/v2/api-docs", "anon");
filterMap.put("/webjars/**", "anon");
filterMap.put("/401", "anon");
filterMap.put("/**", "jwt");
factoryBean.setFilterChainDefinitionMap(filterMap);
return factoryBean;
}
@Bean
public JwtFilter getJwtFilter(){return new JwtFilter();}
比较上两种写法:
第一种
:如果在Filter不会调用注入容器之中的Bean时,第一种写法可用。
第二种
:Filter将被注入spring容器作为全局拦截器,这样即便路由在放行的情况下也会被拦截。
正确示例
通过构造函数注入Filter,这样JwtFilter中就能够使用已经注入容器中的Bean,同时不向 Spring容器中注册 JWTFilter Bean,防止 Spring 将 JWTFilter 注册为全局过滤器,全局过滤器会对所有请求进行拦截,而本例中只需要拦截除 /login 和 /logout 外的请求。
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager,JwtFilter jwtFilter) { // 通过构造注入。
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
//拦截器filter
HashMap<String, Filter> requestFilterMap = new HashMap<>();
requestFilterMap.put("jwt", jwtFilter);
factoryBean.setFilters(requestFilterMap);
//自定义过滤器
Map<String, String> filterMap = new HashMap<>();
// 访问401和404页面不通过我们的Filter
filterMap.put("/user/login", "anon");
filterMap.put("/user/register", "anon");
filterMap.put("/doc.html", "anon");
filterMap.put("/swagger-resources", "anon");
filterMap.put("/v2/api-docs", "anon");
filterMap.put("/webjars/**", "anon");
filterMap.put("/401", "anon");
filterMap.put("/**", "jwt");
factoryBean.setFilterChainDefinitionMap(filterMap);
return factoryBean;
}
//禁止JwtFilter全局注入。
@Bean
public FilterRegistrationBean<Filter> registration(JwtFilter jwtFilter) {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>(jwtFilter);
registration.setEnabled(false);
return registration;
}