跳至主要內容

Spring Security太复杂?试试这个轻量级权限认证框架!

TJ君原创开源推荐开源Spring Security大约 11 分钟

各位程序猿小伙伴们,中秋快乐~在节日欢快的气氛中大家是不是还在奋笔疾书、沉浸在学习的海洋中呢?

小编这两天休息在家一直在想一个问题,那就是我们在开发SpringBoot项目的时候,该怎么做好权限认证呢?之前有和小伙伴讨论的时候说起过一些常见的相关框架,例如Shiro或者Spring Security等,但这些框架似乎在运用上存在着各种美中不足的地方,尤其是用起来太过复杂,劝退了不少新手程序猿,让人总觉意犹未尽。

不过呢,就在这个假期里,小编发现了一个新的权限认证框架,总体感觉使用起来简单明了,整体的API设计呢也属上乘,所以赶紧来和大家分享下~

他就是,权限认证框架领域一块璀璨的明珠~~~下面让我们有请:

Sa-Token

Spring Security太复杂?试试这个轻量、强大、优雅的权限认证框架

Sa-Token,可能是史上功能最全的Java权限认证框架之一!或者可以去掉之一两字。

截止目前为止,Sa-Token已集成——登录认证、权限认证、分布式Session会话、微服务网关鉴权、单点登录、OAuth2.0、踢人下线、Redis集成、前后台分离、记住我模式、模拟他人账号、临时身份切换、账号封禁、多账号认证体系、注解式鉴权、路由拦截式鉴权、花式token生成、自动续签、同端互斥登录、会话治理、密码加密、jwt集成、Spring集成、WebFlux集成等等等等各种各样的丰富内容。

看着这么多功能似乎有种让人眼花的感觉,没事没事,浓缩一下精华,其实你只要记住:

Sa-Token 作为一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0、微服务网关鉴权 等一系列权限相关问题。

Sa-Token的一大优点就是API设计简单不冗余复杂。有多简单?可能光说不够直观,小编带你看下他的登录认证:

// 在登录时写入当前会话的账号id
StpUtil.login(10001);

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

就上面短短的两句话,我们已经完成了登录认证。用过其他框架的小伙伴可能现在满脑在都是问号,什么?自定义 Realm 呢?全局过滤器呢?各种配置文件吗?

是的,相对于前文提到的Shiro、Spring Security, Sa-Token就是如此的简单便捷,更加适合当今时代的潮流与效率至上。

小编再举两个例子,例如权限认证:

(只有具备 user:add 权限的会话才可以进入请求)

@SaCheckPermission("user:add")
@RequestMapping("/user/insert")
public String insert(SysUser user) {
 // ... 
 return "用户增加";
}

又例如账号登出:

将某个账号踢下线(待到对方再次访问系统时会抛出NotLoginException异常)

// 使账号id为 10001 的会话强制注销登录
StpUtil.logoutByLoginId(10001);

不止以上这些功能,其实在Sa-Token里,绝大多数功能都可以只用一行代码完成,听着很神奇是吧?但事实就是这样:

StpUtil.login(10001);                     // 标记当前会话登录的账号id
StpUtil.getLoginId();                     // 获取当前会话登录的账号id
StpUtil.isLogin();                        // 获取当前会话是否已经登录, 返回true或false
StpUtil.logout();                         // 当前会话注销登录
StpUtil.logoutByLoginId(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.logoutByLoginId(10001, "PC");     // 指定设备标识进行强制注销 (不同端不受影响)
StpUtil.openSafe(120);                    // 在当前会话开启二级认证,有效期为120秒 
StpUtil.checkSafe();                      // 校验当前会话是否处于二级认证有效期内,校验失败会抛出异常 
StpUtil.switchTo(10044);                  // 将当前会话身份临时切换为其它账号 

有小伙伴可能要问了,那么这么简单好用的Sa-Token到底支持哪些功能啊?其实就是前文看着晕乎乎那一堆功能,不过如果小编给你整理一下,你就会觉得清晰无比:

功能一览

  • 登录认证 —— 单端登录、多端登录、同端互斥登录、七天内免登录
  • 权限认证 —— 权限认证、角色认证、会话二级认证
  • 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太复杂?试试这个轻量、强大、优雅的权限认证框架

Spring Security太复杂?试试这个轻量、强大、优雅的权限认证框架

项目目录结构:

── sa-token
    ├── sa-token-core                         // [核心] Sa-Token 核心模块
    ├── sa-token-starter                      // [整合] Sa-Token 与其它框架整合
        ├── sa-token-servlet                      // [整合] Sa-Token 整合 Servlet容器实现类包
        ├── sa-token-spring-boot-starter          // [整合] Sa-Token 整合 SpringBoot 快速集成 
        ├── sa-token-reactor-spring-boot-starter  // [整合] Sa-Token 整合 Reactor响应式编程 快速集成 
        ├── sa-token-solon-plugin                 // [整合] Sa-Token 整合 Solon 快速集成 
    ├── sa-token-plugin                       // [插件] Sa-Token 插件合集
        ├── sa-token-dao-redis                    // [插件] Sa-Token 整合 Redis (使用jdk默认序列化方式)
        ├── sa-token-dao-redis-jackson            // [插件] Sa-Token 整合 Redis (使用jackson序列化方式)
        ├── sa-token-spring-aop                   // [插件] Sa-Token 整合 SpringAOP 注解鉴权
        ├── sa-token-temp-jwt                     // [插件] Sa-Token 整合 jwt 临时令牌鉴权 
        ├── sa-token-quick-login                  // [插件] Sa-Token 快速注入登录页插件 
        ├── sa-token-alone-redis                  // [插件] Sa-Token 独立Redis插件,实现[权限缓存与业务缓存分离]
        ├── sa-token-oauth2                       // [插件] Sa-Token 实现 OAuth2.0 模块 
    ├── sa-token-demo                         // [示例] Sa-Token 示例合集
        ├── sa-token-demo-springboot              // [示例] Sa-Token 整合 SpringBoot 
        ├── sa-token-demo-webflux                 // [示例] Sa-Token 整合 WebFlux 
        ├── sa-token-demo-jwt                     // [示例] Sa-Token 集成 jwt 
        ├── sa-token-demo-solon                   // [示例] Sa-Token 集成 Solon 
        ├── sa-token-demo-quick-login             // [示例] Sa-Token 集成 quick-login 模块 
        ├── sa-token-demo-alone-redis             // [示例] Sa-Token 集成 alone-redis 模块
        ├── sa-token-demo-sso1                    // [示例] Sa-Token 集成 SSO单点登录-模式一简单测试
        ├── sa-token-demo-sso1-server             // [示例] Sa-Token 集成 SSO单点登录-模式一 认证中心 
        ├── sa-token-demo-sso1-client             // [示例] Sa-Token 集成 SSO单点登录-模式一 应用端 
        ├── sa-token-demo-sso2-server             // [示例] Sa-Token 集成 SSO单点登录-模式二 认证中心
        ├── sa-token-demo-sso2-client-h5          // [示例] Sa-Token 集成 SSO单点登录-模式二 应用端
        ├── sa-token-demo-sso2-server             // [示例] Sa-Token 集成 SSO单点登录-模式二 认证中心 (前后端分离)
        ├── sa-token-demo-sso2-client-h5          // [示例] Sa-Token 集成 SSO单点登录-模式二 应用端 (前后端分离)
        ├── sa-token-demo-sso3-server             // [示例] Sa-Token 集成 SSO单点登录-模式三 认证中心
        ├── sa-token-demo-sso3-client             // [示例] Sa-Token 集成 SSO单点登录-模式三 应用端
        ├── sa-token-demo-oauth2-server           // [示例] Sa-Token 集成 OAuth2.0 (服务端)
        ├── sa-token-demo-oauth2-client           // [示例] Sa-Token 集成 OAuth2.0 (客户端)
    ├── sa-token-doc                          // [文档] Sa-Token 开发文档 
    ├──pom.xml                                // [依赖] 顶级pom文件 

可能又有小伙伴会问,这么好用?引用集成起来难吗?当然也是非常简单的。

引用依赖

在项目中直接通过 pom.xml 引入依赖即可

<!-- Sa-Token 权限认证 -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.26.0</version>
</dependency>

然后在application.yml中增加如下配置,就可以使用框架啦:

server:
    # 端口
    port: 8081

# Sa-Token配置
sa-token: 
    # token名称 (同时也是cookie名称)
    token-name: satoken
    # token有效期,单位s 默认30天, -1代表永不过期 
    timeout: 2592000
    # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
    activity-timeout: -1
    # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) 
    is-concurrent: true
    # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) 
    is-share: false
    # token风格
    token-style: uuid
    # 是否输出操作日志 
    is-log: false

尝试运行

新建包 com.pj ,在此包内新建主类 SaTokenDemoApplication.java,输入以下代码:

@SpringBootApplication
public class SaTokenDemoApplication {
    public static void main(String[] args) throws JsonProcessingException {
        SpringApplication.run(SaTokenDemoApplication.class, args);
        System.out.println("启动成功:Sa-Token配置如下:" + SaManager.getConfig());
    }
}

再创建一个测试类

@RestController
@RequestMapping("/user/")
public class UserController {

    // 测试登录,浏览器访问:http://localhost:8081/user/doLogin?username=zhang&password=123456
    @RequestMapping("doLogin")
    public String doLogin(String username, String password) {
        // 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对 
        if("zhang".equals(username) && "123456".equals(password)) {
            StpUtil.login(10001);
            return "登录成功";
        }
        return "登录失败";
    }

    // 查询登录状态,浏览器访问:http://localhost:8081/user/isLogin
    @RequestMapping("isLogin")
    public String isLogin() {
        return "当前会话是否登录:" + StpUtil.isLogin();
    }

}

尝试运行,启动代码,从浏览器依次访问下面这些测试接口就可以了:

Spring Security太复杂?试试这个轻量、强大、优雅的权限认证框架

是不是有点感觉了?Sa-Token 还提供了详细的线上指导文档,绝对手把手教你学会使用这个框架。不会用的情况,绝对是不存在的!

想必小伙伴们都已经迫不及待想试试这个看似神奇又简单易用的框架了?

扫描下方二维码,关注公众号“TJ君”,回复“权限控制”,获取仓库地址!

上次编辑于:
贡献者: 程序猿DD