session json()中文乱码_SpringBoot 整合Shiro实现动态权限加载更新+Session共享+单点登录...

一.说明

Shiro是一个安全框架,项目中主要用它做认证,授权,加密,以及用户的会话管理,虽然Shiro没有SpringSecurity功能更丰富,但是它轻量,简单,在项目中通常业务需求Shiro也都能胜任.

二.项目环境

MyBatis-Plus版本: 3.1.0

SpringBoot版本:2.1.5

JDK版本:1.8

Shiro版本:1.4

Shiro-redis插件版本:3.1.0

数据表(SQL文件在项目中):数据库中测试号的密码进行了加密,密码皆为123456

数据表名中文表名备注说明
sys_user系统用户表基础表
sys_menu权限表基础表
sys_role角色表基础表
sys_role_menu角色与权限关系表中间表
sys_user_role用户与角色关系表中间表

Maven依赖如下:

<dependencies>

配置如下:

# 配置端口
server:
  port: 8764
spring:
  # 配置数据源
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/my_shiro?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
  # Redis数据源
  redis:
    host: localhost
    port: 6379
    timeout: 6000
    password: 123456
    jedis:
      pool:
        max-active: 1000  # 连接池最大连接数(使用负值表示没有限制)
        max-wait: -1      # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-idle: 10      # 连接池中的最大空闲连接
        min-idle: 5       # 连接池中的最小空闲连接
# mybatis-plus相关配置
mybatis-plus:
  # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
  mapper-locations: classpath:mapper/*.xml
  # 以下配置均有默认值,可以不设置
  global-config:
    db-config:
      #主键类型 AUTO:"数据库ID自增" INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
      id-type: auto
      #字段策略 IGNORED:"忽略判断"  NOT_NULL:"非 NULL 判断")  NOT_EMPTY:"非空判断"
      field-strategy: NOT_EMPTY
      #数据库类型
      db-type: MYSQL
  configuration:
    # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
    map-underscore-to-camel-case: true
    # 返回map时true:当查询数据为空时字段返回为null,false:不加这个查询数据为空时,字段将被隐藏
    call-setters-on-nulls: true
    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

三.编写项目基础类

用户实体,Dao,Service等在这里省略,请参考源码

编写Exception类来处理Shiro权限拦截异常

/**
 * @Description 自定义异常
 * @Author Sans
 * @CreateTime 2019/6/15 22:56
 */

创建SHA256Util加密工具

/**
 * @Description Sha-256加密工具
 * @Author Sans
 * @CreateTime 2019/6/12 9:27
 */

创建Spring工具

/**
 * @Description Spring上下文工具类
 * @Author Sans
 * @CreateTime 2019/6/17 13:40
 */

创建Shiro工具

/**
 * @Description Shiro工具类
 * @Author Sans
 * @CreateTime 2019/6/15 16:11
 */

创建Shiro的SessionId生成器

/**
 * @Description 自定义SessionId生成器
 * @Author Sans
 * @CreateTime 2019/6/11 11:48
 */

四.编写Shiro核心类

创建Realm用于授权和认证
/**
 * @Description Shiro权限匹配和账号密码匹配
 * @Author Sans
 * @CreateTime 2019/6/15 11:27
 */

创建SessionManager类

/**
 * @Description 自定义获取Token
 * @Author Sans
 * @CreateTime 2019/6/13 8:34
 */

创建ShiroConfig配置类

/**
 * @Description Shiro配置类
 * @Author Sans
 * @CreateTime 2019/6/10 17:42
 */

五.实现权限控制

Shiro可以用代码或者注解来控制权限,通常我们使用注解控制,不仅简单方便,而且更加灵活.Shiro注解一共有五个:
注解名称说明
RequiresAuthentication使用该注解标注的类,方法等在访问时,当前Subject必须在当前session中已经过认证.
RequiresGuest使用该注解标注的类,方法等在访问时,当前Subject可以是“gust”身份,不需要经过认证或者在原先的session中存在记录.
RequiresUser验证用户是否被记忆,有两种含义:一种是成功登录的(subject.isAuthenticated()结果为true);另外一种是被记忆的(subject.isRemembered()结果为true).
RequiresPermissions当前Subject需要拥有某些特定的权限时,才能执行被该注解标注的方法.如果没有权限,则方法不会执行还会抛出AuthorizationException异常.
RequiresRoles当前Subject必须拥有所有指定的角色时,才能访问被该注解标注的方法.如果没有角色,则方法不会执行还会抛出AuthorizationException异常.

一般情况下我们在项目中做权限控制,使用最多的是RequiresPermissions和RequiresRoles,允许存在多个角色和权限,默认逻辑是AND,也就是同时拥有这些才可以访问方法,可以在注解中以参数的形式设置成OR

示例
//拥有一个角色就可以访问

使用顺序:Shiro注解是存在顺序的,当多个注解在一个方法上的时候,会逐个检查,知道全部通过为止,默认拦截顺序是:RequiresRoles->RequiresPermissions->RequiresAuthentication-> RequiresUser->RequiresGuest

示例
//拥有ADMIN角色同时还要有sys:role:info权限
@RequiresRoles(value={"ADMIN")
@RequiresPermissions("sys:role:info")

创建UserRoleController角色拦截测试类

/**
 * @Description 角色测试
 * @Author Sans
 * @CreateTime 2019/6/19 11:38
 */

创建UserMenuController权限拦截测试类

/**
 * @Description 权限测试
 * @Author Sans
 * @CreateTime 2019/6/19 11:38
 */

创建UserLoginController登录类

/**
 * @Description 用户登录
 * @Author Sans
 * @CreateTime 2019/6/17 15:21
 */

六.POSTMAN测试

登录成功后会返回TOKEN,因为是单点登录,再次登陆的话会返回新的TOKEN,之前Redis的TOKEN就会失效了
9c6bc9aff485fb32df79d73883ce98e8.png

当第一次访问接口后我们可以看到缓存中已经有权限数据了,在次访问接口的时候,Shiro会直接去缓存中拿取权限,注意访问接口时候要设置请求头.

b5ef1f459036c8a26fe3d37cf5a6df11.png
95eb0657107ca54094dbd8c1d4d6fdac.png

ADMIN这个号现在没有sys:info:all这个权限的,所以无法访问getInfoAll接口,我们要动态分配权限后,要清掉缓存,在访问接口时候,Shiro会去重新执行授权方法,之后再次把权限和角色数据放入缓存中

dded384e429282836112ce2c11d960b9.png

访问添加权限测试接口,因为是测试,我把增加权限的用户ADMIN写死在里面了,权限添加后,调用工具类清掉缓存,我们可以发现,Redis中已经没有缓存了

04f9adf4faba6ea9f5e44673ba1802d7.png
428439bab7c62bb7a7bd5c514d0703c4.png

再次访问getInfoAll接口,因为缓存中没有数据,Shiro会重新授权查询权限,拦截通过

159223fd203325dc1331f9ada037edfe.png

七.项目源码

码云: gitee.com/liselotte/spring-boot-shiro-demo

GitHub:github.com/xuyulong2017/my-java-demo

作者:Sans_
链接:juejin.im/post/5d087d605188256de9779e64

1f9d9dbfd037a24ecab81a59186ec967.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值