shiro是一款很强大的安全管理、权限认证框架。可以做登录权限管理,接口权限管理。如下,可以通过页面权限按钮控制用户是否拥有查询、新增、编辑的权限,完成后功能如下:在管理登录后给普通用户设置权限,可以是菜单权限,也可以是菜单列表查询权限和列表按钮权限。其中菜单的权限可以只通过代码逻辑控制,而列表查询和按钮接口的权限就可以交给shiro来管理。
直接上实现步骤吧。
大的步骤一:前期需要准备的表和功能(如果系统已有类似的表或功能,或者不需要菜单管理 只做权限管理的就跳过这一步)
1,sys_menu(菜单表)
2,sys_role_menu(角色菜单关联表<多对多>)
3,sys_authorities (权限表)
4,sys_role_authorities(角色权限关联表<多对多>)
5,sys_role(角色表)、sys_user(用户表)、sys_user_role(用户角色关联表<多对多>)。这三张表一般的系统都会有。
-------------以上是需要准备的表,表关系、字段说明、建表sql已经上传至我的资源,欢迎下载,链接如下-------------
https://download.csdn.net/download/nienianzhi1744/12015139
其中理解起来可能稍微难的一点是sys_authorities这张表,这张表有两个疑问点,
问一:表中的authority字段,是什么,这个字段的值是从哪来的,作用是什么。
答一:这个字段的值是swagger自动扫描的接口路径,如post:/v1/user/query。获取到接口路径后再把这个字符串存到表中。作用是在用户前端调用接口的时候,将路径加入shiro的权限管理器中比对,校验用户是否有权限。
例一:如下面这个UserController的list接口方法,由于在方法上指定了post类型及路径"/query",所以这个list的接口路径是post:/v1/user/query(而不是post:/v1/user/list),那么swagger扫描出来的路径也是post:/v1/user/query。那么怎么扫描呢,只需要ajax通过get方式访问 /v2/api-docs 这个接口即可。至于swagger是什么,或者怎么配置,传送门:https://blog.csdn.net/nienianzhi1744/article/details/102622722 ( 只需要看文档中的swagger部分的内容即可)
问二: 表中的parent_menu_id、auth_type字段是什么,怎么来,作用是什么。
答二:parent_menu_id是接口所属父级菜单id,auth_type是接口类型(增删改查导出发送等等),方便授权时查看。怎么来的,当然是有个权限管理的列表,有个编辑按钮,手动选择当前权限时属于哪个菜单下的(因为swagger扫描完系统的接口后不会识别接口是属于哪个菜单或者哪个列表的,需要我们手动做功能选择),同时选择接口类型。作用是方便我们在授权管理时将接口权限与菜单关联,做到批量授权,同时也方便理解。如果只做权限管理不做菜单管理的话可以视情况加。
大的步骤二:
1,pom文件,添加3个jar包
<!--权限认证相相关-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.3.1</version>
</dependency>
2,目录结构。在com.xxx后面建一个shiro目录,shiro目录下建一个config目录,一个realm目录。
两个目录加起来5个文件,这五个文件的作用是:
ehcache.xml:缓存配置。由于加了接口权限的功能,每次调用接口,shiro都会进行权限比较,但权限数据是存在我们数据库的sys_authorities表和sys_role_authorities表。难道每次访问一个接口都要去数据库中查一遍权限?当然不是的,由于我们上面添加了ehcache的jar包,所以我们登录系统后第一次查权限从数据库中查,然后把查到的权限存到缓存中即ehcache中,在后面就可以从缓存中查询权限。至于将这个把权限存到数据库中再拿出来比较的过程,交给shiro就好了,不需要手动写。(这不重要)
EhCacheManager:缓存配置。内容比较简单,赋值粘贴吧(这不重要)
RetryLimitHashedCredentialsMatcher:并发处理。内容比较简单,赋值粘贴吧(这不重要)
ShiroConfig:shiro配置类。在项目启动的时候会扫描到这个类,与springmvc的been配置文件类似。只要配置处理拦截资源文件过滤器,ehcache缓存管理器,自动登录管理器,realm认证及授权管理器这几个管理器。(这是最重要的文件一)
ShiroRealm:shiro登录认证及权限认证管理器。(这是最重要的文件二)
下面依次将这五个文件贴出来。
ehcache.xml:
<ehcache>
<diskStore path="java.io.tmpdir"/>
<!--
maxElementsInMemory:内存存储数据的个数
eternal:缓存数据是否永久有效 建议false
timeToIdleSeconds:最大空闲时间 (s) 空闲时间超出配置,清理内存数据
timeToLiveSeconds:存活时间(s)
overflowToDisk: 溢出到磁盘(磁盘最多存储多少个对象) 如果内存超过maxElementsInMemory配置那么放置到配置的磁盘路径上
diskPersistent: 服务器重启时是否保留磁盘数据
diskExpiryThreadIntervalSeconds: 每隔多长时间进行线程扫描
memoryStoreEvictionPolicy:淘汰策略 LRU(最近最少) FIFO(先进先出 Frist in Frist out)
-->
<defaultCache
maxElementsInMemory="10000"
timeToIdleSeconds="86400"
timeToLiveSeconds="86400"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="86400"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
<!-- 设定缓存的默认数据过期策略 -->
<cache name="shiro"
maxElementsInMemory="10000"
timeToIdleSeconds="86400"
timeToLiveSeconds="86400"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="86400"
memoryStoreEvictionPolicy="LRU">
</cache>
<!-- 登录记录缓存 锁定86400秒,即一天 -->
<cache name="passwordRetryCache"