查看: 1|回复: 1

Sa-Token v1.46.0 发布 🚀,来看看有没有令你心动的功能!

[复制链接]

1

主题

0

回帖

3

积分

新手上路

积分
3
发表于 4 天前 | 显示全部楼层 |阅读模式
Sa-Token 是一款 开源、免费 的轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、单点登录、OAuth2.0、微服务网关鉴权 等一系列权限相关问题。🔐



目前最新版本 v1.46.0 已推送至 Maven 中央仓库 🎉,大家可以通过如下方式引入:

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

Spring Boot 3.x 请改用 sa-token-spring-boot3-starter,Spring Boot 2.x 请改用 sa-token-spring-boot-starter。

该版本包含大量 ⛏️️️新增特性、⛏️底层重构、⛏️️️代码优化 等,下面容我列举几条比较重要的更新内容供大家参阅:

📦 更新点 1:新增 sa-token-fory-json 插件,JSON 方案再添一位

这是官方规划里「 JSON 模块集成 Apache Fory 」的落地,把 Fory JSON 接到 SaJsonTemplate 上。

此前 Session / Redis 序列化主要是 Jackson ( Boot 默认,JSON 里会写 @class)和 Fastjson2 / Snack (默认不写类型信息)。相对 Jackson:Fory 官方文档给出的吞吐更高,且默认不写类型信息,避开多态反序列化那条面;相对 Fastjson2:用法接近,适合已经在用 Apache Fory 、或不想再绑 Fastjson 栈的项目。引入后 SPI 自动注入,不用自己包一层。

<!-- Sa-Token 整合 Apache Fory JSON -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-fory-json</artifactId>
    <version>1.46.0</version>
</dependency>

JSON 插件全家桶现在是:Jackson 、Jackson3 、Fastjson 、Fastjson2 、Fory JSON、Snack3 、Snack4 。Boot 2/3 默认仍是 Jackson ,Boot 4 默认 Jackson3 ,用得顺不必为了换而换。

在线文档:JSON 序列化扩展 🔗

🌐 更新点 2:新增 sa-token-rest-client / sa-token-rest-template 插件

SSO 模式三的 ticket 校验、单点注销、消息推送都要发 HTTP 。此前只有 Forest 、OkHttps 两套第三方客户端。Spring 项目本来就有 spring-web,再为 SSO 拉一套 HTTP 库,依赖和 API 都多一层。

本版按官方规划补上 Spring 官方客户端:sa-token-rest-template、sa-token-rest-client。相对 Forest / OkHttps:不引入第三方 HTTP 栈,跟 Spring 一条线。RestClient 相对 RestTemplate:它是 Spring Framework 6.1+ / Boot 3.2+ 的官方继任者,Boot 4 里 RestTemplate 已标记 deprecated ,新项目优先 RestClient 。Boot 2 或 Boot 3.0–3.1 没有 RestClient,继续用 RestTemplate 或 Forest 。

<!-- Spring Boot 3.2+ / 4 优先 RestClient -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-rest-client</artifactId>
    <version>1.46.0</version>
</dependency>

运行环境
推荐插件

非 Spring / Solon
sa-token-forest 或 sa-token-okhttps

Spring Boot 2 ,或 Boot 3.0–3.1
sa-token-rest-template 或 sa-token-forest

Spring Boot 3.2+ / 4
优先 sa-token-rest-client

同一 classpath 只放一个 HTTP 插件。没配任何处理器会报错误码 30010 。本版还加了 SSO Client 的 Spring Boot 4 示例。

在线文档:HTTP 请求扩展 🔗

🗄️ 更新点 3:新增 sa-token-alone-redisson 插件,权限缓存和业务缓存拆开

来自 GitHub #710、Gitee #ICE2V0:alone-redis 要能配独立 Redisson 。

升级有什么用: 现在 redisson 集成也可以做到权限缓存和业务缓存分离了,会话数据和业务 Redis 不再挤在同一个 Client 上,key 冲突、误删、codec 打架都能避开。Boot 4 另有 sa-token-alone-redis-by-spring-boot4。

<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-alone-redisson</artifactId>
    <version>1.46.0</version>
</dependency>

引入后不必再引 sa-token-redisson / sa-token-redisson-spring-boot-starter。

sa-token:
    alone-redisson:
        config:
            singleServerConfig:
                address: "redis://127.0.0.1:6379"
                database: 2

config 与 file 二选一。示例覆盖单机、集群、Boot 3/4 。

Boot 4 注意:Redisson 3.45 的 starter 仍引用已移除的 RedisAutoConfiguration,不要引 redisson-spring-boot-starter,自己注册 Bean 。SaTokenDaoForRedisson 默认 StringCodec,并可用 setAndKeepTTL 原子保留 TTL 。fix: #791

在线文档:独立 Redisson 插件 🔗

🔧 更新点 4:RedisTemplate 检索改 SCAN 、update 保 TTL 、key 可加前缀

这几条都是社区老工单:

searchData 用 KEYS 会堵 Redis:#702

update 后续期 TTL 偏移:#I80P5O#ICWJOQ

多项目共用 Redis 要加前缀:#956

升级有什么用: 在线用户查询不再 KEYS *;改 Session 不会把过期时间抹成「再活一整段 timeout 」;多系统共 Redis 可以 wrapKey 隔离开。

public class MySaTokenDao extends SaTokenDaoForRedisTemplate {
    @Override
    public String wrapKey(String key) {
        return "my-app:" + key;
    }
}

KEEPTTL 需要 Redis >= 6.0 。

🔔 更新点 5:注销前侦听器,会话清掉之前还能读现场

来自 sa-token 小助手用户「潮汐」的建议:侦听器触发时设备信息往往已经没了,审计不好记。

升级有什么用: 踢人、顶人、主动注销前,还能读到 Token-Session 、设备列表,写日志、发通知不用自己抢时序。

@Override
public void doBeforeLogout(String loginType, Object loginId, String tokenValue, SaLogoutParameter logoutParameter) {
    SaSession session = SaManager.getStpLogic(loginType).getSessionByLoginId(loginId, false);
    SaTerminalInfo terminal = session == null ? null : session.getTerminal(tokenValue);
    // 记注销日志
}

对应钩子:doBeforeLogout / doBeforeKickout / doBeforeReplaced。不要用 StpUtil 读当前请求上下文,用参数里的 loginId、tokenValue 去查。

在线文档:全局侦听器 🔗

📋 更新点 6:Session 新增 getList / getSet / getMap

本版主动补齐。以前从 Session 取集合,要么 get 完再强转,要么自己处理 Redis 回来的裸 List 。现在把元素类型写在参数上,主要是为了让代码写得更优雅,调用更友善。

// 以前
@SuppressWarnings("unchecked")
List<SysUser> users = (List<SysUser>) session.get("users");

// 现在
List<SysUser> users = session.getList("users", SysUser.class);
Set<String> roles = session.getSet("roles", String.class);
Map<String, Long> scoreMap = session.getMap("scoreMap", String.class, Long.class);

// 缺 key 时给默认集合
session.getList("users", SysUser.class, ArrayList::new);

OAuth2 索引、SSO Client 列表、ApiKey 索引也切到这套 API ,业务侧同一套写法。

在线文档:Session 会话 🔗

🚪 更新点 7:SSO 客户端支持按账号单点注销

社区提案:子系统删用户时,希望一行 API 通知认证中心把该账号全端打下线。

升级有什么用: 后台封号、离职回收,不必再自己拼 SSO 推送报文。

// sso-server
SaSsoServerUtil.ssoLogout(loginId);

// sso-client (本地 loginId ,框架按策略转成认证中心 id )
SaSsoClientUtil.ssoLogout(loginId);

在线文档:Sa-Token SSO 单点注销 🔗

🧩 更新点 8:SaRequest / SaResponse / SaStorage 可策略创建

来自 GitHub #841:旧版靠继承 SaTokenContextForSpring 改上下文,v1.42 重构后那套父类没了。

升级有什么用: Nginx 改 URI 、自定义 Request 包装,改策略函数即可,不用再继承已删除的上下文类。

SaStrategy 新增 createSaRequest / createSaResponse / createSaStorage。getSaTokenConfig 也可接管配置来源,方便从数据库读 Sa-Token 配置。

⚠️ 更新点 9:两处不向下兼容,升级先看

1 )allowLoginIdColon 默认 false 。 官方一直强调 loginId 不要带冒号(持久化 key 用 : 分段)。本版源码直接拒登。存量项目如果 loginId 里真有冒号:

sa-token:
    allow-login-id-colon: true

2 )StpInterface.isDisabled 增加 loginType 参数。 自己实现了封禁查询的,要改方法签名。

另外:JWT extraData 禁止写入 loginType、loginId、deviceType、eff、rnStr 等保留字段,撞名会直接抛错。

🛡️ 更新点 10:修复 OAuth2 / SSO redirect 绕过 allow-url 漏洞

来自社区用户提交的漏洞报告:OAuth2 调用 /oauth2/doConfirm 时,redirect_uri 校验可被绕过;本版审查后确认 SSO 的 redirect 存在同类问题。

触发条件为(需同时满足):

项目搭了 SSO 认证中心 或 OAuth2 授权服务器;

请求里可以由前端(或攻击者)传入 redirect / redirect_uri;

allow-url 配了不安全通配(如 http://domain*,*出现在域名部分,前面不是/或:)。

普通登录鉴权、没用 SSO/OAuth2 的项目,与这条无关。allow-url: "*" 等于主动放开白名单,也不在本条讨论范围。

会造成: ticket 或授权码被下发到第三方站点。

新版本: SSO 与 OAuth2 两侧同时拒绝 @、%40、%2540;* 只能出现在最后一位,且前一位必须是 / 或 :;isUrl 支持 IPv6 方括号地址。生产环境请把 allow-url 配成明确地址。用了 SSO/OAuth2 的,建议升到 v1.46.0 。

sa-token:
    sso-server:
        clients:
            sso-client1:
                allow-url: http://sa-sso-client1.com:9003/*

感谢这位社区用户提交的漏洞报告。

🔐 更新点 11:修复 Jackson 多态反序列化漏洞,新增类型白名单

这是本版对 JSON 反序列化路径的主动审查:使用 Jackson / Jackson3 把 SaSession 写入 Redis 时,JSON 里会带 @class 类型标记;旧版本未限制严格限制反序列化类型白名单,可能会在反序列化时触发 classpath 上的任意类。

触发条件为(需同时满足): 使用 SaJsonTemplate 去反序列化业务中未严格审查的 json 字符串。

fastjson / fastjson2 / fory-json / snack3 默认不写类型标记,一般不走这条面。不去使用 SaJsonTemplate 去反序列化业务中未严格审查的 json 字符串。本版起 sa-token-snack3 也不再写入类型信息。

会造成: 攻击者提交恶意 json 字符串,可能触发多态反序列化 RCE 。

新版本: 增加 SaJsonStrategy 全局类型白名单,只允许白名单内类型参与这类反序列化。JDK 常见值类型、框架已实现 SaJsonType 的 Model 默认在名单里;你的业务实体默认不在。用了 Jackson 且 Session 里存了自定义对象的,升级后可能看到:

无法反序列化的类型:com.pj.model.SysUser ,请先将其注册到 JSON 全局类型白名单

推荐让实体实现 SaJsonType:

public class SysUser implements SaJsonType {
    // ...
}

也可以在 SpringApplication.run 之前 调用 SaJsonStrategy.instance.registerAllowType(SysUser.class),或在 META-INF/satoken/sa-json-type.list 按行写完整类名。JSON 插件初始化后再注册会失败。不要登记 Object.class。用了 Jackson + SaJsonTemplate 反序列化业务 json 字符串的,建议升到 v1.46.0 ,并先把业务类型登记进白名单。

在线文档:JSON 序列化扩展 🔗

📡 更新点 12:修复 SSE / Flux 上下文未初始化,以及 Boot3 WebFlux setStatus

这两条都是社区报错工单:SSE 来自 Gitee #IC4XFE#ICB9OJ;setStatus 来自 #IIAW1A、GitHub #916

SSE / Flux

在之前的版本中,SpringMVC 接口如果返回 SseEmitter、Flux 等异步、流式结果,随后再调 StpUtil / SaHolder 会报:

cn.dev33.satoken.exception.SaTokenContextException: SaTokenContext 上下文尚未初始化

这是因为 Context Filter 只注册了 REQUEST。流式返回会再走一遍 ASYNC dispatch ,过滤器没挂上,ThreadLocal 上下文是空的。普通 @RequestMapping 一问一答不受影响。

新版本把 Filter 注册为 REQUEST + ASYNC,二次 dispatch 也会初始化上下文,一般不用再手改 Filter 。

Boot3+ WebFlux / Gateway setStatus

在之前的版本中,Boot3+ 的 WebFlux 或 Gateway 里调用:

SaHolder.getResponse().setStatus(401);

会报:

java.lang.NoSuchMethodError: 'org.springframework.http.server.reactive.ServerHttpResponse setStatusCode(org.springframework.http.HttpStatus)'

这是因为 Boot2 的 ServerHttpResponse.setStatusCode 吃 HttpStatus,Boot3 改成了 HttpStatusCode,旧 Reactor starter 字节码对不上。WebMVC 用户与这条无关。

新版本拆了 Boot2 / Boot3+ 的 Reactor 实现,Boot3+ 走 HttpStatusCode.valueOf(sc),不再报错。sa-token-dependencies 也不再锁死 Reactor 版本,避免跟 Spring Cloud Gateway 打架。fix: #622

📚 更新点 13:文档站启用 .com 顶级域名,博客、多语言、安全策略

域名从 sa-token.cc 迁到 sa-token.com,请即使修改书签。独立博客上线;文档站暗色主题 5 种 IDE 风格; translate.js 多语言; README 有英/日/韩/俄/繁中。

随机数改用 SecureRandom。新增 SECURITY.md:安全问题走 GitHub Private Vulnerability Reporting 或邮件,不要开公开 Issue 。

文档版本选择器改为动态加载。Solon 插件由 PathAnalyzer 换成 PathMatcher 。

感谢 @Ran 补充 SECURITY.md( fix #932#877);感谢 @noear 适配 Solon PathMatcher ( fix #IJTNJK)。

📜 完整更新日志

除了以上提到的几点以外,还有更多更新点无法逐一详细介绍,下面是 v1.46.0 版本的完整更新日志:

core:
新增:侦听器新增注销前钩子 doBeforeLogout / doBeforeKickout / doBeforeReplaced。 [重要]

新增:StpInterface.isDisabled 补充 loginType 参数。  [不向下兼容]

新增:新增 allowLoginIdColon 配置,默认禁止 loginId 包含冒号。  [不向下兼容]

修复:Jackson DefaultTyping 多态反序列化 RCE ,新增 SaJsonStrategy 全局类型白名单。  [重要] [漏洞修复]

新增:getSaTokenConfig 策略支持自定义配置来源,方便从数据库中读取配置。

新增:新增 SaRequest / SaResponse / SaStorage 创建策略。  fix: #841

新增:Session 新增 getList / getSet / getMap 类型安全集合读取。

修改:随机字符串/数字改用 CSPRNG (SecureRandom)生成。

修复:isLastingCookie 为 null 时 getCookieTimeout 不再 NPE 。

修复:isUrl 支持 IPv6 方括号地址并拒绝裸 IPv6 。

修复:JSON 反序列化容错优化。  fix: #ICOTM8

插件:
新增:新增 sa-token-fory-json JSON 序列化插件。  [重要]

新增:新增 HTTP 请求扩展插件 sa-token-rest-client / sa-token-rest-template。  [重要]

新增:新增 sa-token-alone-redisson 独立连接插件及 Spring Boot 3/4 示例。  [重要]  fix: #710#ICE2V0

新增:新增 sa-token-alone-redis-by-spring-boot4 插件及示例,实现 Spring Boot 4 下权限缓存与业务缓存分离。  [重要]

新增:SaTokenDaoForRedisson 支持指定 Codec (默认 StringCodec),update 方法改用 setAndKeepTTL 原子保留原过期时间。  [重要]  fix: #791

修复:sa-token-redis-template 及 jdk-serializer 在 update key 时 TTL 偏移的问题。  [重要]  fix: #I80P5O#ICWJOQ

修复:redis-template searchData 由 KEYS 改为 SCAN 。  [重要]  fix: #702

新增:RedisTemplate Dao 支持重写 wrapKey 自定义键前缀。  fix: #956

修复:sa-token-redis-template-jdk-serializer KEEPTTL 泛型编译错误。

修复:Snack3 序列化不再写入类型信息,对齐 fastjson 安全策略。  [漏洞修复]

修复:集成 JWT 时 extraData 禁止包含保留字段。  [不向下兼容]

优化:升级 fastjson / fastjson2 至 2.0.64 。

优化:sa-token-dependencies 不再锁定 Reactor 版本,避免与 Spring Cloud Gateway 冲突。  fix: #622

starter:
修复:Context Filter 注册 REQUEST+ASYNC ,修复 SSE/Flux 流式返回上下文未初始化。  [重要]  fix: #IC4XFE#ICB9OJ

修复:Boot3+ WebFlux/Gateway setStatus NoSuchMethodError 。  fix: #IIAW1A#916#IHRIBY

新增:新增 SSO Client Spring Boot 4 示例。

新增:新增 sa-token-demo-first-run 首次运行引导示例。

修复:demo-ssm 适配 v1.42.0+ 上下文机制。

Solon:
优化:sa-token-solon-plugin 由 PathAnalyzer 适配改为 PathMatcher ,优化 Config 示例。  merge: pr 364  fix: #IJTNJK

优化:升级依赖 noear-redisx 至 1.8.5 、noear-snack4 至 4.0.59 。

SSO:
修复:OAuth2/SSO redirect 参数绕过 allow-url 校验的安全漏洞。  [重要] [漏洞修复]

新增:SSO 客户端新增指定账号单点注销 API 。

补全:补全最新版 SSO NoSdk 模式实现,新增 SsoSignUtil。

修复:buildServerAuthUrl 识别 URL 编码后的 back 参数,back 为空时跳过追加,并增强重定向编码/解码健壮性。  fix: #842

修复:getClient 统一通过 getClients 查找以支持子类覆盖。

修复:NoSdk demo 签名校验补充时间窗与 nonce 防重放。  [漏洞修复]

修复:订正 SSO-Client 接收消息推送地址的路由说明。

OAuth2:
修复:redirect 参数绕过 allow-url 校验的安全漏洞。  [重要] [漏洞修复]

修改:expiresTime 为 -1 时按永久有效存储 Token 。

重构:doConfirm 确认授权流程统一校验。

重构:SaOAuth2Dao 改用带 Class 参数的 getObject 反序列化。  fix: #IK5GYU

修复:OAuth2 demo 拒绝授权时回传 state 。

新增:OAuth2 章节补充数据互通后的 token 过期策略说明。

文档:
修改:全仓库域名 sa-token.cc 统一迁移至 sa-token.com 。  [重要]

新增:上线独立博客系统,收录原创文章。  [重要]

新增:文档站点多语言切换(基于 translate.js )。  [重要]

新增:README 多语言版本(英文、日文、韩文、俄文、繁体中文)与切换入口。  [重要]

新增:新增 SECURITY.md 安全策略及联系邮箱。  [重要]  merge: pr 933  fix: #932#877

新增:文档站点暗色主题切换,支持 5 种 IDE 风格。

新增:文档版本选择器改为动态加载(all-version-common.js)。  merge: pr 928  fix: #900

新增:新增源码运行指南文档。

新增:新增「 Sa-Token 集成 Demos 示例大全下载」文档。

新增:导航栏增加安全推荐与案例下拉菜单。

优化:文档站点整体优化(侧边栏、首页、捐赠页、导航交互、API 手册等)。

同步:同步公众号文章列表、博客列表、赞助者名单、企业登记案例。

补充:补充 SSE/Flux 流式返回常见问题;补充按配置决定是否启用 Redis 的示例。  fix: #I9I4ZG

修复:订正 API 手册、SSO/OAuth2/WebFlux/Dubbo 等文档错漏。

其它:
新增:新增乐之者 java B 站视频教程链接。  [重要]

优化:统一日志文案用词,「帐号」改为「账号」。

优化:统一 token 续期相关注释措辞。

修复:修正 ConcurrentHashMap 的错误 import 路径。  merge: pr 359

更新日志在线文档直达链接:https://sa-token.com/doc.html#/more/update-log

🌟 其它

代码仓库地址: https://gitee.com/dromara/sa-token

框架功能结构图:

回复

使用道具 举报

0

主题

65

回帖

130

积分

注册会员

积分
130
发表于 4 天前 | 显示全部楼层
大家真的想在这里看更新点吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖
返回顶部