【若依(ruoyi)】 Shiro 向 ShiroFilterFactoryBean 中添加自定义过滤器

前言

  • 若依(ruoyi): v4.3
  • shiro: 1.5.3
  • 遇坑:shiro 自定义过滤器执行异常,无法排除已允许匿名访问的功能/URL

需求

使用 ruoyi 开发 restful 接口。因此,仅需要ruoyi开放如下功能:

  • swagger-ui.html(为了更好的测试才开放,生产部署时去掉这个)
  • /v2/api-docs(为了更好的测试才开放,生产部署时去掉这个)
  • /api/** (所有的接口均以/api/开头)

除了上述需要开放的功能外,其余均不允许访问。

ruoyi 使用 shiro 进行权限控制。因此需要通过配置 shiro 来达到目的。

操作

实现思路

  • 将所需开放的功能配置为允许匿名访问
  • 将不需要开放的功能均拒绝访问

编写拒绝访问的 shiro 过滤器

public class DenyAllFilter extends PathMatchingFilter {

	@Override
    protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) {
		HttpServletRequest hsr = (HttpServletRequest) request;
		System.out.println("DenyAllFilter, request is not allow : " + hsr.getRequestURI());
		return false;
    }
}

修改 ShiroConfig


    /**
     * Shiro过滤器配置
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager)
    {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // Shiro的核心安全接口,这个属性是必须的
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        
        // 自定义过滤器
        Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
        filters.put("denyAllFilter", denyAllFilter());
        shiroFilterFactoryBean.setFilters(filters);
        
        // 定义过滤器链
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/api/**", "anon");
        filterChainDefinitionMap.put("/v2/api-docs**", "anon");
        filterChainDefinitionMap.put("/swagger**", "anon");
        filterChainDefinitionMap.put("/webjars/**", "anon");
        filterChainDefinitionMap.put("/swagger-resources/**", "anon");
        filterChainDefinitionMap.put("/favicon.ico**", "anon");
        filterChainDefinitionMap.put("/**", "denyAllFilter");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }
    
    @Bean
    public DenyAllFilter denyAllFilter()
    {
    	DenyAllFilter denyAllFilter = new DenyAllFilter();
        return denyAllFilter;
    }

嗯…,这就好了。
出了有坑之外,一切都很完美。

有坑

有坑不怕,填上就行。

启动ruoyi,访问地址http://localhost:8085/aswagger-ui.html,得到了个很白的页面。这是遇到坑了。这个坑不分析了,有兴趣的可以参考这里

说一下结论:

  • 这里遇到的坑是:不该将 filter 交给 spring 创建。

简单解释一下:

  • shiro 的权限控制是通过 filter 控制的,且 shiro 自己维护了一个 filter chain。
  • spring 也维护了一个 filter chain。
  • denyAllFilter 交给 spring 创建后, denyAllFilter 虽然如愿的加入到了 shiro filter chain 中,但,同时也加入到了 spring filter chain 中。

解决办法:
denyAllFilter 不交给 spring 创建即可。将 denyAllFilter 方法前面的 @Bean 注解去掉即可。

    public DenyAllFilter denyAllFilter()
    {
    	DenyAllFilter denyAllFilter = new DenyAllFilter();
        return denyAllFilter;
    }

参考

https://www.cnblogs.com/guitu18/p/12163872.html

猜你喜欢

转载自blog.csdn.net/sayyy/article/details/108443668