现象:

 利用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;
}
最后修改:2024 年 11 月 25 日
如果觉得我的文章对你有用,请随意赞赏