其实我也是刚刚接触到Shiro,还没怎么用的好,只是这几天搭建环境,然后学到了点东西,拿出来给大家炫耀一下😋。
搭建的环境目标,想要通过Shiro验证token来控制用户的权限。具体搭建,可以参考大佬:一看就懂!Springboot+Shiro+VUE前后端分离式权限管理系统_大誌的博客-CSDN博客 。我整个项目都是按照这个大哥的博客搭建的!他讲的步骤很详细。
我这里主要简单介绍一下此次学到关于shiro自定义token认证的工作流程,也只是在这个项目里学到的,可能只是片面的,不够全面,大家可以参考一下。
我们自定义shiro的token验证,一定要扩展它的Filter 和 Reaml。为了下面描述,我暂时给这两个类起个名字:
A. public class MyFilter extends AuthenticatingFilter{}
B. public class MyRealm extends AuthorizingRealm{}
但是自定义token的话,还得实现一个接口:
C. public class MyToken implements AuthenticationToken;
or 继承 UsernamePasswordToken
public class MyToken extends UsernamePasswordToken;
MyFilter 里,主要重写
1. createToken() : 获取请求里的token,并封装成一个MyToken对象;
2. isAccessAllowed(): 主要放行OPTIONS请求(跨域引起的复杂请求)然后其余请求都返回false;
3. onAccessDenied() :用于调用executeLogin()
MyRealM里,重写
1.doGetAuthenticationInfo(): 验证用户方法
2.doGetAuthorizationInfo() :用户授权方法
3.supports() :如果 C 处,继承了UsernamePasswordToken,那么这里不需要重写这个方法;如果继承了AuthenticationToken,则需要重写:

实现流程:
1. 前端发起请求后,会被我们自定义的Filter拦截,进入到 isAccessAllowed() 里。因为其好几代的父类:AccessControlFilter 里有一个方法:onPreHandle()

2. 可以看出,想要执行 onAccessDenied(),必须让isAccessAllowed()返回false!所以,处了OPTIONS 请求,都返回false。
3. 在 onAccessDenied()里,简单校验一下请求里的token合法性,如果不合法让用户重新登录,如果合法,则调用 executeLogin()。当然,我们没有重写,调用的是从父类继承过来的方法。so,we need to look look 其源码。
4.

关键的两个地方:因为createToken()在父类里是抽象的,必须重写!

再看一下 MyToken对象:

所以,createToken() 就是单纯的获取了请求里的token,并存储了起来(注意重写的这两个方法,下面有伏笔的)。
再回到第4步的开始

第一句我们知道了,获取请求里的token,并封装成一个 AuthenticationToken 对象。
第二句判断 token是否为空,注意这的token是AuthenticationToken对象,并不是我们在请求中获取的字符串token!所以这里的 if 判断铁定不能为null,有null才是异常!
不为空后,就调用了subject.login()。众所周知,调用subject.login()就回进入到Realm的 doGetAuthenticationInfo()。
5.用户信息验证

用户信息验证成功后,进入到 doGetAuthorizationInfo() : 授权方法。验证方法和授权方法的名字听相似,大家写代码的时候要注意哦!
6.授权:根据获取到的用户,获取其对应的角色,然后根据角色获取对应的权限。

7。进入方法:shiro会把方法上 @RequiresPermissions 里的值与授权方法返回的 SimpleAuthorizationInfo 对象里的权限集合去对比,如果存在该权限,则允许方法,如果不存在,则抛出异常


当然,对于这种频繁的查询,建议集成下redis。
网友评论