Skip to content

1.3.1版本发布

Choose a tag to compare

@llllllxy llllllxy released this 09 Aug 11:51
· 33 commits to master since this release

tiny-security 1.3.1 升级日志

发布日期:2026-08-09
升级路径:1.3.0 → 1.3.1
适用分支:springboot3(Spring Boot 3.x / JDK 17+) 和 springboot2(Spring Boot 2.x / JDK 8)


一、版本概览

1.3.1 是一个架构重构 + 性能优化 + 安全加固版本。本次更新移除了全局静态单例模式,改为 Spring 原生依赖注入;修复了会话调度线程泄露问题;优化了授权检查的 Redis 访问次数;新增了异常响应状态码控制配置项;同时移除了存在安全隐患的加密工具类。

维度 说明
新增特性 2 项(异常 HTTP 状态码强制 200、授权按需查询优化)
Bug 修复 1 项(会话调度线程泄露)
破坏性变更 3 项(GlobalConfig 移除、AuthProperties 迁移、AESUtil/RSAUtil 删除)
涉及提交 6 次功能性提交 + 1 次版本发布
代码变更 +1,288 / -840 行(含测试)

二、新增特性

2.1 异常响应 HTTP 状态码强制 200(force-http-status-200)

提交: 8199d0c

背景: 部分前端框架(如 axios)对非 2xx 状态码会触发异常拦截,导致业务错误码需要额外处理。新增此配置后,异常响应统一返回 HTTP 200,由响应体 code 字段表达真实业务错误。

配置方式:

tiny-security:
  force-http-status-200: true  # 默认 false

行为说明:

配置值 HTTP 状态码 响应体 code 字段
false(默认) 真实错误码(401/403/409/500) 真实业务错误码
true 统一 200 真实业务错误码(401/403/409/500)

兼容性: 前端判错逻辑无需改动——无论开关如何,响应体 code 字段始终保留真实业务错误码。DefaultExceptionTranslator 保留了无参构造函数,向后兼容。


2.2 授权检查按注解类型按需调用 SPI

提交: d4e9e67

背景: 1.3.0 中,一个接口即使只标注了 @RequiresRoles,授权管理器仍会同时查询角色和权限(两次 Redis 访问);反之亦然。

优化内容: DefaultAuthorizationManager 现根据注解类型按需调用 SPI:

接口注解 1.3.0 行为 1.3.1 行为
仅 @RequiresRoles 查角色 + 查权限 仅查角色
仅 @RequiresPermissions 查角色 + 查权限 仅查权限
同时标注两者 查角色 + 查权限 查角色 + 查权限
PermissionMode.URL 查角色 + 查权限 查角色 + 查权限(URL 模式始终查权限)

收益: 单注解场景下 Redis 访问次数减半。


三、Bug 修复

3.1 会话调度线程泄露修复

提交: 68e6c7b、3756b8e(补充单测)

问题: JDBC 会话仓储(JdbcSessionRepository)和本地缓存(LocalTimeCache)各自创建了 ScheduledExecutorService 调度线程,但在应用停机时没有真正 shutdown。LocalTimeCache.endRefreshThread() 仅将 refreshFlag 标记设为 false,线程本身仍在运行。

影响场景:

  • 应用正常停机时线程未关闭
  • Spring DevTools 热重启导致线程累积
  • 多上下文(如 Spring MVC + WebSocket)场景下线程泄露

修复方案:

类 修复方式
JdbcSessionRepository 实现 DisposableBean,destroy() 中调用 executorService.shutdownNow()
SingleSessionRepository 实现 DisposableBean,destroy() 中调用 timedCache.endRefreshThread()
LocalTimeCache 移除 refreshFlag 标记机制,endRefreshThread() 改为直接 executorService.shutdownNow()

四、破坏性变更(⚠️ 升级必读)

4.1 移除 GlobalConfig / GlobalConfigUtils 全局静态单例

提交: 776dac9

变更说明:

项目 1.3.0 1.3.1
配置持有方式 GlobalConfig 全局静态单例 + GlobalConfigUtils 访问器 Spring 容器依赖注入
初始化时机 ContextRefreshedEvent 事件监听 Bean 构造时注入
AuthAutoConfiguration 实现 ApplicationListener<ContextRefreshedEvent> 移除该接口,改为构造注入

删除的类:

  • org.tinycloud.security.config.GlobalConfig(217 行)
  • org.tinycloud.security.config.GlobalConfigUtils(66 行)

升级影响:

  • 如果你的代码中直接调用了 GlobalConfig.getXxx() 或 GlobalConfigUtils.getGlobalConfig(),需要改为通过 Spring 注入获取对应 Bean。
  • 框架内部所有拦截器、AuthProvider 已改为构造注入,框架自身使用不受影响。

4.2 AuthProperties 包路径迁移

提交: 776dac9

项目 1.3.0 1.3.1
所在模块 tiny-security-boot-starter tiny-security-core
完整路径 org.tinycloud.security.AuthProperties org.tinycloud.security.config.AuthProperties

升级影响:

  • 如果你通过 import 引用了 AuthProperties,需要更新 import 路径。
  • yml 配置前缀 tiny-security 不变,无需修改配置文件。
  • @EnableConfigurationProperties(AuthProperties.class) 注解由 AuthAutoConfiguration 自动处理,用户通常无感知。

4.3 移除 AESUtil 和 RSAUtil 加密工具类

提交: 7cb7eb3

删除的类:

  • org.tinycloud.security.util.secure.AESUtil(196 行)
  • org.tinycloud.security.util.secure.RSAUtil(128 行)

删除原因:

  1. 对称/非对称加密不属于认证框架职责边界
  2. AESUtil 存在硬编码默认密钥安全隐患
  3. RSAUtil 未使用 OAEP 填充,存在安全风险
  4. 框架核心代码从未引用这两个类

保留的算法:

类别 算法 类名 状态
摘要算法 MD5 / SHA-256 / SM3 DigestUtil / SM3Hash ✅ 保留
密码哈希 BCrypt BCrypt ✅ 保留

升级影响: 如果你的业务代码使用了 AESUtil 或 RSAUtil,请迁移至以下替代方案:

  • JDK JCA(javax.crypto.*)
  • Hutool(cn.hutool.crypto.*)
  • BouncyCastle

五、架构改进

5.1 引入 TinySecurityFacade 门面模式

提交: 776dac9

新增 org.tinycloud.security.TinySecurityFacade(180 行),设计参照 Sa-Token 的 StpUtil/StpLogic 模式:

AuthUtil(静态外观,用户调用不变)
    ↓ delegate
TinySecurityFacade(Spring Bean,构造注入依赖)
    ↓
SecurityContextRepository / AuthorizationEvaluator

设计要点:

  • AuthUtil 是静态外观类,用户侧调用方式(AuthUtil.getLoginId() 等)完全不变
  • TinySecurityFacade 是 Spring Bean,通过构造注入获取 SecurityContextRepository
  • 内部依赖可测试、可替换,解决了全局静态单例不可 Mock 的问题

5.2 拦截器改为构造注入

提交: 776dac9

拦截器 1.3.0 依赖获取方式 1.3.1 依赖获取方式
AuthenticationInterceptor 从 GlobalConfig 静态获取 构造注入 AuthenticationManager + SecurityContextRepository
AuthorizationInterceptor 从 GlobalConfig 静态获取 构造注入 AuthorizationManager + SecurityContextRepository + SecurityEventPublisher + AuthProperties

六、升级指南

6.1 Maven 依赖升级

<!-- Spring Boot 3.x -->
<dependency>
    <groupId>top.lxyccc</groupId>
    <artifactId>tiny-security-boot3-starter</artifactId>
    <version>1.3.1</version>
</dependency>

6.2 升级检查清单

按以下顺序检查你的项目:

  • 步骤 1: 全局搜索 GlobalConfig 和 GlobalConfigUtils,如有引用需改为 Spring 注入方式
  • 步骤 2: 全局搜索 org.tinycloud.security.AuthProperties 的 import,更新为 org.tinycloud.security.config.AuthProperties
  • 步骤 3: 全局搜索 AESUtil 和 RSAUtil,如有使用迁移至 JCA / Hutool / BouncyCastle
  • 步骤 4: 如果自定义了 DefaultExceptionTranslator,确认是否需要传入 forceHttpStatus200 参数
  • 步骤 5: 检查是否有代码直接依赖 LocalTimeCache.refreshFlag 字段(已移除)
  • 步骤 6: 验证 AuthUtil 调用方式未变(正常情况下无需改动)

6.3 兼容性说明

用户侧 API 兼容性
AuthUtil.getLoginId() 等静态方法 ✅ 完全兼容,调用方式不变
yml 配置 tiny-security.* ✅ 完全兼容,前缀不变
@RequiresRoles / @RequiresPermissions ✅ 完全兼容
自定义 SessionRepository ✅ 兼容(建议实现 DisposableBean 管理线程)
自定义 ExceptionTranslator ✅ 兼容(DefaultExceptionTranslator 保留无参构造)
直接使用 GlobalConfig ❌ 已移除,需改为注入
直接使用 AESUtil / RSAUtil ❌ 已移除,需迁移

七、提交记录

序号 提交哈希 日期 类型 说明
1 d4e9e67 2026-07-18 feat 授权检查按注解类型按需调用 SPI,减少 Redis 访问
2 68e6c7b 2026-07-18 fix 会话调度线程泄露修复(JdbcSessionRepository / SingleSessionRepository / LocalTimeCache)
3 3756b8e 2026-07-18 test 补充 SessionRepositoryLifecycleTest 生命周期单测
4 8199d0c 2026-08-07 feat 新增 force-http-status-200 异常响应状态码配置项
5 7cb7eb3 2026-08-08 refactor 移除 AESUtil 和 RSAUtil 加密工具类
6 776dac9 2026-08-08 refactor 重构安全框架配置和依赖注入机制(移除 GlobalConfig,引入 TinySecurityFacade)
7 e54d4e8 2026-08-09 release 版本号升级至 1.3.1

八、致谢

感谢所有贡献者和使用者的反馈与支持。如遇升级问题,请提交 Issue。