简介
说明
本文用实例展示Shiro的使用,SpringBoot整合Shiro,并通过Session控制权限。
- 尽量使用原生的shiro配置,尽量少自定义配置。
- 我自己自测通过,代码可用。
shiro用法我写了一个系列,有如下文章:
- Shiro整合jwt-通过注解控制权限 – 自学精灵
- Shiro整合jwt-通过url控制权限 – 自学精灵
- Shiro整合Session-通过注解控制权限 – 自学精灵
- Shiro整合shiro-redis – 自学精灵
使用形式
- 使用Shiro默认的session来管理权限。
- 使用Shiro默认的缓存来放session。
- 用本地Map存session,重启即失效。
- 本地Map意味着只能单机,无法多个服务共享session。
- 使用角色和资源权限两种方式。(注解的方式)
- 使用Shiro默认的过滤器。
- 使用Knife4j测试(Swagger的升级版)。
- 使用shiro-spring-boot-web-starter:1.7.0
技术栈
- shiro-spring-boot-web-starter:1.7.0
- spring-boot-starter-parent:2.3.8.RELEASE
- mysql:8.0
- mybatis-plus-boot-starter:3.4.3.1(持久层框架)
- lombok(简化代码)
- knife4j-spring-boot-starter:3.0.3(接口文档(swagger的升级版))
业务场景
本文假设做一个商城系统。
角色如下
- admin:有所有权限
- 使用shiro通配符:*:*
- productManager:有product的所有权限
- product:add,product:delete,product:edit,product:view
- 本处把这四个权限单独赋予productManager这个角色,实际项目里可以将product:*这个权限赋予productManager这个角色。
- orderManager:有order的所有权限
- order:add,product:delete,product:edit,product:view
- 本处把这四个权限单独赋予productManager这个角色,实际项目里可以将product:*这个权限赋予productManager这个角色。
用户密码及权限如下
用户 | 密码 | 角色 | 拥有的权限 |
zhang3 | 12345 | admin | 所有权限。 |
li4 | abcde | productManager | 产品的所有权限。 |
本处为了测试功能,赋予以下特殊权限:
- 验证shiro可单独通过角色来控制权限
- 给编辑订单接口设置角色权限:
- @RequiresRoles(value = {“admin,productManager”}, logical = Logical.OR)
- 给编辑订单接口设置角色权限:
- 验证shiro无法在一个接口上同时加@RequiresRoles和@RequiresPermissions
- 给查看订单的接口设置角色权限与资源权限:
- @RequiresPermissions(“order:view”)
@RequiresRoles(value = {“admin,productManager”}, logical = Logical.OR)
- @RequiresPermissions(“order:view”)
- 给查看订单的接口设置角色权限与资源权限:
结果展示
测试超级管理员(admin)
启动项目,访问:http://localhost:8080/doc.html

1.测试登录
- 登录成功
- 可以看到,会返回来一个JSESSIONID。

2.测试有资源权限的接口
本处测试增加产品接口。
- 成功访问。
- 在请求时会传递cookie(JSSESSIONID)

3.测试登出

4.再次访问接口
- 访问失败
- 跳转到loginUrl指定的地址(本处是/login)
- 因为我们用的是默认过滤器,authc对应FormAuthenticationFilter,它里边有个逻辑:如果认证失败,则跳转到loginUrl对应的网址。
- 所以,要取消这个跳转,可以自己实现过滤器,不跳转到loginUrl即可。后边我会写一个shiro+jwt的博客,里边使用自定义过滤器,不跳转到loginUrl。

测试产品管理员(productManager)
启动项目,访问:http://localhost:8080/doc.html

1.测试登录
- 登录成功
- 可以看到,会返回来一个JSESSIONID。

2.测试有资源权限的接口
本处测试增加产品接口。
- 成功访问。
- 在请求时会传递cookie(JSSESSIONID)

3.测试无资源权限的接口
本处测试增加订单接口。
- 访问失败。
- 在请求时会传递cookie(JSSESSIONID)

4.测试有角色权限的接口
本处测试编辑订单接口。
- 访问成功。
- 在请求时会传递cookie(JSSESSIONID)

5.测试无角色权限的接口
本处测试删除订单接口。
- 访问失败。
- 在请求时会传递cookie(JSSESSIONID)

重启服务再请求
1.登录
登录成功

2.重启服务器
重启Idea启动的应用。
3.访问有权限的接口
本处访问产品增加接口。
- 可以看到,访问失败。但我们本次访问是带着上次的JSESSIONID的。
- 说明:重启后授权就没了,也就是说:SESSION是存在了内存中的。

代码
此内容仅限VIP查看,请先登录
请先
!