Shiro和SpringSecurity用起来太繁琐,推荐一个好用的权限认证框架

2021-12-20 16:37:45 浏览数 (1)

权限认证的方式有很多,传统上Java体系可以用shiro或者spring security,如果是非常简单的项目也可以自己写一个拦截器,后端生成token,然后用户登录的时候从redis中取出对比,但是这几种方式都有不如意的地方,今天我们来说说权限认证框架的选型,希望给大家开发项目的过程中带来一些参考。

基本概念

安全框架有2个核心概念,分别是认证(Authentication)和授权(Authorization)。

一般通过用户名和密码来完成认证;授权指的是对资源的访问控制权限,哪些资源可以访问,哪些资源没有权限访问,这是授权要做的事,通过为用户分配不同的角色(管理员、用户、编辑)这样的形式来完成授权。

shiro

核心概念

Subject、SecurityManager、Realms。

subject至用户,可以是人,也可以是请求的程序,代表与后台交互的主体。

securityManager顾名思义,是安全管理的意思,管理用户的安全权限。

realm可以理解为一个连接层,shiro会通过一个或多个realm中查找获取用户权限,realm需要自己配置。

shiro的特点

  • 代码比较易懂
  • 支持一级缓存,提升性能
  • 独立运行,不依赖于Spring

总结一下,shiro的最大的特点就是不依赖Spring,如果你的项目不是spring项目就可以考虑用shiro了。

SpringSecurity

spring官方出品,可spring深度绑定的权限框架。

核心概念

其实spring security的核心概念就是servlet过滤器,通过多个过滤器形成的过滤器链来完成权限校验。

例如 Basic Authentication Filter 就是验证用户身份,还有username password Authentication Filter,会检查请求是否有用户名和密码。

Spring security的特点

  • 功能齐全
  • 配置复杂
  • 性能一般
  • 深度绑定Spring

功能比shiro齐全的多,不需要自己手动实现太多代码,但是没法脱离spring,换句话说现在Java的web开发有多少不用spring呢,这个限制好像也没什么了。

satoken

比较喜欢的第三方轮子,知名度还是不低的,类似于hutool那样小而美的工具。

支持的特性如下:

登录认证 —— 单端登录、多端登录、同端互斥登录、七天内免登录

权限认证 —— 权限认证、角色认证、会话二级认证

Session会话 —— 全端共享Session、单端独享Session、自定义Session

踢人下线 —— 根据账号id踢人下线、根据Token值踢人下线

账号封禁 —— 指定天数封禁、永久封禁、设定解封时间

持久层扩展 —— 可集成Redis、Memcached等专业缓存中间件,重启数据不丢失

分布式会话 —— 提供jwt集成、共享数据中心两种分布式会话方案

微服务网关鉴权 —— 适配Gateway、ShenYu、Zuul等常见网关的路由拦截认证

单点登录 —— 内置三种单点登录模式:无论是否跨域、是否共享Redis,都可以搞定

OAuth2.0认证 —— 基于RFC-6749标准编写,OAuth2.0标准流程的授权认证,支持openid模式

二级认证 —— 在已登录的基础上再次认证,保证安全性

Basic认证 —— 一行代码接入 Http Basic 认证

独立Redis —— 将权限缓存与业务缓存分离

临时Token验证 —— 解决短时间的Token授权问题

模拟他人账号 —— 实时操作任意用户状态数据

临时身份切换 —— 将会话身份临时切换为其它账号

前后台分离 —— APP、小程序等不支持Cookie的终端

同端互斥登录 —— 像QQ一样手机电脑同时在线,但是两个手机上互斥登录

多账号认证体系 —— 比如一个商城项目的user表和admin表分开鉴权

花式token生成 —— 内置六种Token风格,还可:自定义Token生成策略、自定义Token前缀

注解式鉴权 —— 优雅的将鉴权与业务代码分离

路由拦截式鉴权 —— 根据路由拦截鉴权,可适配restful模式

自动续签 —— 提供两种Token过期策略,灵活搭配使用,还可自动续签

会话治理 —— 提供方便灵活的会话查询接口

记住我模式 —— 适配[记住我]模式,重启浏览器免验证

密码加密 —— 提供密码加密模块,可快速MD5、SHA1、SHA256、AES、RSA加密

全局侦听器 —— 在用户登陆、注销、被踢下线等关键性操作时进行一些AOP操作

开箱即用 —— 提供SpringMVC、WebFlux等常见web框架starter集成包,真正的开箱即用

因为用的人不少,所以安全性还是能得到一定保证的,如果是前后端分离的场景,用spring security和shiro并不是很方便,推荐大家尝试一下satoken,就个人的使用感受来说,

api简单,基本都是一两行代码搞定,以登录认证为例:

代码语言:javascript复制
// 在登录时写入当前会话的账号id
StpUtil.login(10001);

// 然后在需要校验登录处调用以下方法:
// 如果当前会话未登录,这句代码会抛出 `NotLoginException` 异常
StpUtil.checkLogin();

权限认证示例:

代码语言:javascript复制
@SaCheckPermission("user:add")
@RequestMapping("/user/insert")
public String insert(SysUser user) {
    // ... 
    return "用户增加";
}

将某个账号踢下线:

代码语言:javascript复制
// 将账号id为 10001 的会话踢下线 
StpUtil.kickout(10001);

常用api如下:

代码语言:javascript复制
StpUtil.login(10001);    // 标记当前会话登录的账号id
StpUtil.getLoginId();    // 获取当前会话登录的账号id
StpUtil.isLogin();    // 获取当前会话是否已经登录, 返回true或false
StpUtil.logout();    // 当前会话注销登录
StpUtil.kickout(10001);    // 将账号为10001的会话踢下线
StpUtil.hasRole("super-admin");    // 查询当前账号是否含有指定角色标识, 返回true或false
StpUtil.hasPermission("user:add");    // 查询当前账号是否含有指定权限, 返回true或false
StpUtil.getSession();    // 获取当前账号id的Session
StpUtil.getSessionByLoginId(10001);    // 获取账号id为10001的Session
StpUtil.getTokenValueByLoginId(10001);    // 获取账号id为10001的token令牌值
StpUtil.login(10001, "PC");    // 指定设备标识登录,常用于“同端互斥登录”
StpUtil.kickout(10001, "PC");    // 指定账号指定设备标识踢下线 (不同端不受影响)
StpUtil.openSafe(120);    // 在当前会话开启二级认证,有效期为120秒 
StpUtil.checkSafe();    // 校验当前会话是否处于二级认证有效期内,校验失败会抛出异常 
StpUtil.switchTo(10044);    // 将当前会话身份临时切换为其它账号 

是不是很方便?

总结

  • 如果是非spring项目,使用shiro;
  • 如果是spring项目,使用spring security和satoken,但是由于spring security现在用的比较多,所以我的建议是2个都要学,否则看不懂别人的项目。

点个『赞』或者『在看』再走,勾玉在此谢过~

0 人点赞