近期,工作需求也是涉及到 Shiro 权限的问题,而且目前项目是前后端分离的,所以要求做到实现前后端分离。作为一个攻城狮,自然不能推辞。

        鉴于之前未接触过 SpringBoot 中 用 ShIro 做授权和认证,然后去各大网站上搜了一番,果然,还和以前一样,千篇一律,Copy的居多,而且即使 GitHub 上有 demo 的,下载之后也是跑步不起来,无计可施。

        由于关于 SpringBoot 会涉及到很多版本的问题,所以建议各位,还是选择自己项目需要的版本,而且在未验证此 demo 和方法可行性的情况下,不要 Copy 或者转载到自己博客中,以免误人子弟。

        好了,言归正传,今天就给大家简单说一下, SpringBoot 中怎么用 Shiro 做权限验证,并实现前后端分离,其实没有大家想象的那么难,主要是不要进坑里爬不出来。一旦进坑,要立马回头,不要驻留,要不然浪费的只是自己的时间。

 

先上下源码吧,要不然大家看着也比较枯燥,启动项目,结合源码看博客更易懂。

GitHub :https://github.com/313989006/shiroDemo

项目结构如下:

SpringBoot 集成 Shiro 实现前后端分离

第一步、在IDEA中导入项目,在application.properties 文件中修改自己的 redis 地址。

SpringBoot 集成 Shiro 实现前后端分离

 

第二步、打开 Navicat ,新建数据库,运行 sql.txt 文件,插入表和数据。(表中只造了一点数据,只是测试)

SpringBoot 集成 Shiro 实现前后端分离

第三步、运行 ShiroDemoApplication 文件,启动项目

SpringBoot 集成 Shiro 实现前后端分离

注意:如果遇到启动不成功的情况下,大概率是因为 redis 地址的问题,修改下 redis 地址即可。

 

第四步、发送登陆请求,查看程序运行(debug 状态下)。

SpringBoot 集成 Shiro 实现前后端分离

当然,对于 SpringBoot 项目用的是 Rest 风格的开发方式,前端发送请求都是通过 ajax 请求,后端接收到请求之后,返回 Json 和状态码数据给前端。

JwtFilter 是自定义的过滤器,继承 BasicHttpAuthenticationFilter ,重写 onAccessDenied、 createToken、preHandle 方法。

      a、onAccessDenied :验证是否过滤请求,验证 token 是否有效

      b、createToken : 创建 token

      c、preHandle :设置支持跨域 (SpringBoot 有很多跨域问题,所以最好还是重写preHandle  方法,支持跨域)

发送请求后会先进入 onAccessDenied 方法(过滤是否可以直接访问的 URL,这里userLogin 登陆请求肯定是可以直接访问的,anonymousStr 是在 application.properties 文件中配置的,此处配置为:登陆、登出、图片验证可以直接访问):

SpringBoot 集成 Shiro 实现前后端分离

 

第五步、这里发送登陆请求,会直接到登陆的 API 接口。

       这里是通过查询数据库,判断账号密码是否匹配,如果匹配,则写入 Redis ,返回 code 和 msg 给前端。

SpringBoot 集成 Shiro 实现前后端分离

在请求成功之后,也会在 header 中添加 Authorization  字段,返回给前端,前端保存到本地,请求的时候带着请求头发起请求。

SpringBoot 集成 Shiro 实现前后端分离

 

第六步、发起 test2 请求,这里就是我们要抓住的重点了。

请求时,在header 中带上 Authorization 和刚才登陆返回的 值。

SpringBoot 集成 Shiro 实现前后端分离

 

同样也会先进入JWTFilter 进行过滤,如果是非登陆、登出、图片验证码请求,则会验证 token 是否有效。

当认证通过之后,会进入 MyRealm 的 doGetAuthenticationInfo 方法,进行认证。

SpringBoot 集成 Shiro 实现前后端分离

 认证通过之后,会到 doGetAuthorizationInfo 方法中,进行授权,这里就是授权的核心代码:

SpringBoot 集成 Shiro 实现前后端分离

此处获取 该用户 权限 和 角色,加入到 SimpleAuthorizationInfo 实例化对象中。

SpringBoot 集成 Shiro 实现前后端分离

这里可以看到,我们拿到的当前用户的角色和权限都是 admin ,并且保存在 SimpleAuthorizationInfo 的实例化对象中。

那接下来 F8 到底会不会进入请求的 URL(test2)中呢?答案肯定是:会的,因为 test2 需要的 permission 就是 admin,肯定会正常进入到 test2 的。我们来看下:

SpringBoot 集成 Shiro 实现前后端分离

当然,这里如果改成 @RequiresRoles(“admin”)当然也是可以访问的,因为该用户的 roles 也包含了 admin 的角色。

而后端返回给我们的数据是:

SpringBoot 集成 Shiro 实现前后端分离

也就说明如果该用户有 url 上允许的permissions或者roles的话就可以正常访问该 URL。

 

到这里,我们就验证结束了,相信看到的应该也知道流程是什么样子的,代码没那么复杂。

主要就是通过过滤器 JWTFilter 过滤请求,MyRealm 进行认证和授权,Controller 层通过 @RequiresPermissions 和 @RequiresRoles 注解来实现权限的验证。

 

现在对 Shiro 还有什么不懂的吗?如果还有不懂的话,可以一步步debug ,看底层源码怎么实现的,其实很多时候学习不只是学习到底怎么用的,还要去 Debug 调试去看看他怎么实现的,这样才能学到更多的技术栈。

这里也是我一步步 Debug 来进行验证和实现的,当然也遇到很多坑,但是要及时跳出来,才能找到更好的解决方法。希望和大家一起学习新的技术和知识,欢迎大家一起沟通交流,互相进步。

 

注:

    1、这里 使用的是 SpringBoot 2.1.3版本。

    2、shiro版本:Shiro 1.4.0 版本

    3、开发环境:Java  1.8 版本

    4、数据库驱动:com.mysql.cj.jdbc.Driver (com.mysql.jdbc.Driver 已经被遗弃)

 

 

我是进阶的球儿,大家一起2019年的爬坑历程。感觉分享很给力的话给个赞,谢谢!!!有问题也可以下方留言或者加本人QQ:313989006 进行沟通。

相关文章: