给 Java 后端项目加登录与单点登录(Sa-Token)
Sa-Token 是 dromara 维护的 Java 权限认证框架,把登录会话、权限与角色校验、踢人下线、SSO、OAuth2.0、微服务网关鉴权等能力收进静态方法调用与注解里。这篇文章梳理它的核心模块定位、最短安装示例、主要功能与关键配置项,说明结果在哪儿看,并整理 GitHub Issue 里用户真实踩过的坑,最后给出两个同类项目的横向对照,帮读者判断自己的项目该不该用它。
给一个 Java 后端项目补上登录,要做的事往往比预期多:会话存哪里、令牌怎么发、接口怎么拦、多端登录要不要互斥、网关那一层怎么统一校验。Sa-Token 是 dromara 组织维护的一套 Java 权限认证框架,把这些分散的决定收进了一组静态方法调用里。
Sa-Token 是用 Java 写的开源权限认证框架,输入账号 id 与请求上下文,输出登录会话与权限判断结果,供 SpringBoot 等后端项目做登录、鉴权与单点登录。
它面向的场景很具体:APP、小程序这类不支持 Cookie 的终端也要鉴权;多台服务器之间要共享会话;同一个系统里 User 表和 Admin 表要分开鉴权;再往外走,还要接 SSO 单点登录、OAuth2.0 授权、微服务网关统一认证。仓库地址 https://github.com/dromara/Sa-Token,采用 Apache-2.0 许可证,主要语言 Java,当前 Star 19073、Fork 2912、开放 Issue 118,最近一次提交在 2026-09-27,默认分支为 dev。

它不做什么
README 里专门澄清过一件事:Sa-Token 不是对 Spring Security 的封装,也不是套壳 Apache Shiro。
它的能力边界在 Java 生态内。非 Java 项目想接它的单点登录,走的是 NoSdk 方式,通过 sso-server 的接口对接,不引入 SDK。
持久化不是默认带的。README 把「可集成 Redis,重启数据不丢失」写在持久层扩展这一条里,会话数据要落盘就得自己接 Redis。
商业支持也不提供。文档写明赞助仅为友情赞助,不提供任何商业交换,框架与在线文档承诺永久免费开放。
用之前先准备好什么
环境上,JDK 支持范围是 8 到 25,SpringBoot 2 与 SpringBoot 3/4 都有对应集成包,Solon、JFinal 也在支持列表里。构建工具按 README 是 Maven,依赖坐标写在 pom.xml 中,groupId 固定为 cn.dev33。
要用分布式会话,或者用 SSO 的跨 Redis 模式、前后端不同域的架构,需要先准备可用的 Redis;模式三在前后端不同域、后端也不同 Redis 的情况下使用,还得部署 sso-server。仓库目录里有 sa-token-demo/,SSO 的三种模式各自带可直接运行的示例。
主要功能
登录认证与会话管理。一行 StpUtil.login(10001) 完成会话登录,参数是登录人的账号 id,不需要实现接口或创建配置文件。需要拦截时调用 StpUtil.checkLogin(),未登录会抛 NotLoginException。支持单端登录、多端登录、同端互斥登录与七天免登录,Token 内置六种风格,也可以自定义生成策略。
权限与角色认证。注解方式把鉴权与业务代码分开,方法上写 @SaCheckPermission("user:add"),只有具备该权限的会话才能进入方法。路由拦截方式按模块划分:
registry.addInterceptor(new SaInterceptor(handler -> {
SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
})).addPathPatterns("/**");
一个系统里有多套账号体系时,可以按账号类型分开鉴权,比如商城的 User 表和 Admin 表走各自的登录逻辑。
踢人下线与账号封禁。按账号 id 踢下线写 StpUtil.kickout(10077),也能按 Token 值踢。封禁支持登录封禁、按业务分类封禁和按处罚阶梯封禁。
单点登录 SSO。分三种模式:前端同域加后端同 Redis 用模式一,靠共享 Cookie 同步会话;前端不同域加后端同 Redis 用模式二,靠 URL 重定向传播会话;两个都不满足时用模式三托底,走 HTTP 请求校验 ticket 获取会话。校验环节包含域名校验、ticket 校验与参数签名校验。README 提到一个细节:部分同类框架登录后会把带参数的地址截断,Sa-Token 内的算法保证登录后按原地址返回,参数不丢。
OAuth2.0 授权。四种授权模式覆盖不同场景:授权码式是标准流程,server 下放 code、client 兑换 access_token;隐藏式用 URL 重定向把 access_token 直接给到客户端页面;密码式由 client 拿用户账号密码换 access_token;客户端凭证式发放 client 级别的 client_token,代表应用自身的资源授权。
微服务与 RPC 鉴权。网关层适配 Gateway、ShenYu、Zuul 等常见网关的路由拦截认证;dubbo、grpc 有对应集成包,在 RPC 调用时登录状态不丢失。
API Key、参数签名与临时 Token。API Key 模块与 TOTP 在 v1.42.0 新增;参数签名模块用于跨系统 API 调用的签名校验,防参数篡改与请求重放;TempToken 模块经过重构,新增了用 value 反查 token 的机制,用于短时间的授权需求。
安装与最短示例
在 SpringBoot 项目里引一个依赖即可:
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.46.0</version>
</dependency>
登录与校验各一行静态调用:
// 会话登录,参数填登录人的账号 id
StpUtil.login(10001);
// 校验当前客户端是否已经登录,未登录抛出 NotLoginException
StpUtil.checkLogin();
如果改用 WebFlux 或 Solon,换成对应的 starter 集成包,仓库里为这些框架都提供了集成模块。
关键参数
配置项与接口参数集中在几个地方。allowLoginIdColon 在 v1.46.0 新增,默认禁止 loginId 包含冒号,属于不向下兼容的改动,账号体系里带冒号的要从这里放行。
StpInterface.isDisabled 在 v1.46.0 补充了 loginType 参数,同样不向下兼容;实现该接口做账号禁用判断的代码需要跟着调整。
注销相关参数上,SaLogoutParameter 在 v1.43.0 新增 deviceId,用于控制指定设备 id 的注销。同一账号不允许多客户端同时登录时,v1.45.0 新增的重复登录处理策略可以选择踢人下线或拦截本次登录。自动续期有 active-timeout 这条线,允许在单次请求中跳过续期,避免定时轮询被算作活跃行为。
JSON 序列化上,v1.46.0 针对 Jackson DefaultTyping 的多态反序列化 RCE 增加了 SaJsonStrategy 全局类型白名单,这个属于安全相关配置,升级时不要跳过。
结果在哪里看
控制器只负责业务,鉴权结果以两种方式体现:要么方法正常返回,要么抛出异常,未登录抛 NotLoginException,权限不足时抛对应异常,可以在全局异常处理里统一接管。
会话数据的落点取决于是否接 Redis。不接 Redis 时数据在内存里,README 把「重启数据不丢失」作为集成 Redis 的收益列出;接了 Redis 之后,会话与权限缓存可以从 Redis 里查。仓库另有独立 Redis 的能力,用于把权限缓存与业务缓存分开。
想直接看运行效果,可以跑 sa-token-demo/ 下的示例工程,SSO 三种模式都带了完整可运行的客户端。完整文档在项目官网 sa-token.com。
实际使用中的坑
路由拦截报未能读取到有效 Token。现象是 NestedServletException 里包着 NotLoginException: 未能读取到有效Token,出现版本 1.30,这条 Issue 有 67 条评论,是仓库里讨论最多的一条,当前状态已解决。
SpringBoot 4 适配。SpringBoot 4 正式版发布后有用户提了适配请求,47 条评论,已解决。项目支持列表里明确写着 SpringBoot 2 与 SpringBoot 3/4,用新版本前建议先确认集成包版本。
二次登录导致栈溢出。1.44.0 版本下出现 StackOverflowError,异常从 DispatcherServlet 抛出,16 条评论,已解决。
WebFlux 与网关下拿不到上下文。1.34.0 配 SpringBoot 3.0.1、JDK 17 时概率性抛 InvalidContextException: 未能获取有效的上下文;另一条 1.38.0 的 gateway 场景同类报错共 11 条评论,状态是待解决,用 WebClient 构造请求的写法尤其要注意。template
跨域配置改动后 token 失效。1.43.0 下解决跨域问题之后反而出现 未能读取到有效 token,13 条评论,已解决。CORS 相关的处理函数在 v1.42.0 之后有单独模块,改动跨域策略时值得对照文档检查一遍。
横向对照
下面三个项目按仓库自述都归在身份认证与单点登录这一类里,横向位置供选型参考。
| 项目 | 适合谁 | 部署方式 | 主要限制 | 什么情况下选它更合适 | 项目地址 |
|---|---|---|---|---|---|
| dromara/Sa-Token | 用 SpringBoot、WebFlux、Solon 做后端,希望登录、权限、SSO、网关鉴权一次配齐的 Java 团队 | Maven 引依赖,按需自行接入 Redis;SSO 模式三要自建 sso-server | 会话持久化要自己接 Redis;社区交流以中文为主;v1.46.0 含两处不向下兼容改动 | 鉴权逻辑要嵌在业务应用里,且需要注解与路由两种拦截方式同时可用时 | dromara/Sa-Token |
| apereo/cas | 想把身份认证做成独立服务对外提供单点登录的团队,仓库自述为 Identity & Single Sign On | 仓库没有说明 | 未逐一核实 | 鉴权要从业务应用里彻底剥离,作为独立身份服务存在时,这个方向更贴近 | apereo/cas |
| pac4j/pac4j | 需要在多个 Java Web 框架之间复用同一套认证与授权逻辑的团队,仓库自述为 Java 的安全引擎 | 仓库没有说明 | 未逐一核实 | 项目里框架选型不统一、希望认证层与具体框架解耦时,可以看它 | pac4j/pac4j |
如果团队要做的是跨语言、跨组织的统一身份服务,把认证逻辑嵌进每个后端应用的方案就不合适,apereo/cas 这类以独立身份中心为定位的项目更贴近这种需求。Sa-Token 的中文文档与中文社区对国内团队是省事的地方,反过来也意味着团队里没有中文成员时,可选的求助渠道更少。它更擅长的是单个 Java 应用内部的登录与权限,而不是替代一整套企业级身份基础设施。
适合谁
正在写 SpringBoot 或 WebFlux 后端、要在业务代码里快速加上登录与权限校验的 Java 开发者,用 Sa-Token 省事:引一个依赖,登录与校验各一行,权限可以走注解也可以走路由匹配。
有多套账号体系、要做同端互斥登录、要把会话放到 Redis 做分布式的项目,也能在这里找到对应模块;需要单点登录或 OAuth2.0 时,仓库提供了具体模式和可运行示例。
非 Java 技术栈的团队不适合把 Sa-Token 当主力鉴权方案,它的集成包都围绕 Java 生态,非 Java 项目只能走 NoSdk 方式对接 SSO。需要独立部署身份中心、跨组织对接标准化认证协议的场景,也应该去看 apereo/cas 这类以身份服务为定位的项目。已经在用 Spring Security 且团队对它很熟、现有配置也不复杂的项目,迁移过来收益有限。
焚评:这个项目的量化评分
本项目的选题来自 焚.com(一个按公开公式给 GitHub 项目打分的站)。焚评当前总分 9.7 分(满分 10)。下表是各维度的得分:
| 评分维度 | 得分 |
|---|---|
| 热度动量(权重 25%) | 10.0 / 10 |
| 开发活跃(权重 25%) | 9.3 / 10 |
| 社区响应(权重 15%) | 9.8 / 10 |
| 文档质量(权重 15%) | 10.0 / 10 |
| 发布节奏(权重 10%) | 8.8 / 10 |
| 风险控制(权重 10%) | 10.0 / 10 |
评分口径、权重与计算方式见焚.com 的评分方法页;数据随 GitHub 指标刷新,具体数值以焚.com 当前页面为准。本文正文为诀.com 独立撰写,评分数据由焚.com 授权引用。
内容核验说明
这篇的价值在于把 Sa-Token 的安装、关键配置项和升级风险放在一处,尤其点出 v1.46.0 两处不向下兼容改动、Jackson 反序列化白名单这类容易漏掉的安全配置,再整理了 GitHub Issue 里高频的几类报错,末尾给了与 CAS、pac4j 的横向定位。
文中 Star 19073、Fork 2912、开放 Issue 118、最近提交时间等仓库指标来自 GitHub 公开数据抓取(2026-10-13),焚评分值引自焚.com,诀.com 未独立验证。各类报错现象、版本号与评论数来自 GitHub Issue 提交者的公开描述,属用户报告,本站未复现,结果不保证可复现。安装示例、配置项与功能说明来自项目 README 与在线文档,亦未逐一实测。用户反馈摘要
根据仓库 Issue 来看,问题集中在版本适配与上下文获取:SpringBoot 4 适配、WebFlux 下未初始化上下文或概率性报 InvalidContextException、路由拦截报未能读取到有效 Token,这几条提交者均标注为已解决。另有跨域配置调完后 token 失效、二次登录触发 StackOverflowError、404 请求一并被拦截、SSO 校验通过后重定向闪屏。有提交者提出同一 Redis 被多个项目共用时 token key 可能互相覆盖,建议生成 key 时加可配前缀。以上均为 Issue 报告,未独立复现。
基于该仓库公开 Issue 整理,只反映提交者报告的现象与诉求,不代表诀.com 立场,也不代表问题已被确认。项目来源与说明
开源项目:dromara(dromara)
本文由诀.com 编辑基于该项目的公开信息独立撰写,属原创解读,不是对项目文档的翻译或转载;文中提到的功能与参数以官方仓库为准,代码与文档版权归原作者所有。
查看项目仓库