shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。

背景

当前项目要做改造,项目原先是基于若依框架写的
因此数据权限是若依框架自带的,鉴权认证也是基于纯redis实现的鉴权业务。
现在作为基线版本,为了方便以后更好的开发,决定改为由shiro进行数据权限控制和用户认证。
这里展示下项目结构
shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。_第1张图片

项目自然而然是多模块项目,我将shiro在公共模块的’common-security’里头进行了集成配置
然后在’modules-template’、‘modules-system’、'modules-auth’三个主业务web模块的pom文件中,引入了该公共模块
依赖逻辑如下:
shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。_第2张图片
而在ShiroConfig中,我的ShiroFilterFactoryBean对象是这样配置的。

  @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置securityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //登录url
        //shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setLoginUrl("/auth/login");//该接口来自于auth模块
        //登陆成功后跳转的url
        shiroFilterFactoryBean.setSuccessUrl("/testsuccess");
        //未授权url
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");


        /*
        配置过滤规则Map集合。
        key为资源名(路径,支持模糊)。
        value为资源性质
                anon:无需认证即可访问。
                authc:需要认证才可访问。
                user:点击“记住我”功能可访问
                logout:注销,执行后会跳转到shiroFilterFactoryBean.setLoginUrl()设置的url

          */
        LinkedHashMap<String,String> filterChainDefinitionMap = new LinkedHashMap<>();

        //定义过滤器白名单,以配置公共资源,如不拦截静态资源。
        filterChainDefinitionMap.put("/css/**","anon" );
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/fonts/**", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/config/**", "anon");
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/version/**", "anon");
        filterChainDefinitionMap.put("/code/**", "anon");
        filterChainDefinitionMap.put("/auth/**", "anon");
        filterChainDefinitionMap.put("/auth/login", "anon");


        //配置退出过滤器。
        filterChainDefinitionMap.put("/auth/logout","logout" );//该接口来自于auth模块。
        filterChainDefinitionMap.put("/","anon" );

        //除了以上的url以外,所有url的访问都需要通过认证。未通过认证的话自动跳转到shiroFilterFactoryBean.setLoginUrl()方法设置的url
        filterChainDefinitionMap.put("/seat/**","authc" );//来自template模块
        //filterChainDefinitionMap.put("/**","authc" );

  shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }

通过上述配置类我们得知,我们会对符合’/seat/**'规则的链接,都进行判断,判断其是否进行了认证(即:通过/auth/login接口进行了登录),如果是,则允许访问,否则便跳转到登录页面(/auth/login)。

遇到的问题

此时启动gateway(网关)、auth、template、system这四个模块。
shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。_第3张图片

通过前端页面,进行登录,登录接口便是/auth/login。

shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。_第4张图片
接下来成功登录,说明已经过了认证。
shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。_第5张图片
然后访问其中的’坐席管理’菜单,它所要请求的接口便是/seat/list,而这是一个需要此前通过了认证才能访问的接口。
shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。_第6张图片
shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。_第7张图片
按理说,此前通过了认证(/auth/login),那么应该是不会被拦截才对,然而并非如此。
我们被拦截了:
shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。_第8张图片
这里,我们的问题现象有二个。
现象一:
尽管我在所指定的登录接口‘/auth/login’进行了登录,但是登录后,我访问这个链接时被视为未认证,依然被拦截了。

现象二:
在未被认证后,执行了跳转操作。但跳转链接并非为gateway网关的’http://127.0.0.1:8080/auth/login’,而是变成了192.168.8.128:9208/auth/login,而9208端口恰恰是template模块的端口。
(注意:192.168.8.128是本机内网ip地址)
shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。_第9张图片

原因

造成这二种现象的原因,那就是因为多个模块都注入了shiro,最后各自模块形成了不同的shiro实例
这就造成了auth鉴权模块的’/auth/login’接口尽管进行了登录和认证,
但是template模块和auth模块并非为同一个shiro实例所以template模块中的shiro,并不知道用户通过了认证,因此进行了拦截,而且还错误地把拦截地址给成了template模块地址
shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。_第10张图片

解决

shiro集成在springboot多模块项目中的踩坑,过滤配置失效问题原因和解决。_第11张图片

结论:让网关模块单独集成shiro

解决办法就是,让单个模块集成shiro即可,使其只准有一个统一的shiro实例

前提是所有的前端请求链接都要经过这个模块,那么毫无疑问,这就是gateway网关模块了,因此,我可以只通过gateway网关模块单独引用common-security这个公共模块,从而使其只有一个shiro实例,来解决这个问题。

你可能感兴趣的:(shiro,安全性测试,shiro)