#971·Sa-Token

[Feature] sa-token-sign 多应用模式支持基于 DB / 动态数据源的秘钥存储与注入

Author: Zzzz-zmyCreated Aug 24, 2026Updated Aug 24, 2026

一、背景与现状

当前 sa-token-sign 的多应用模式(文档第 11 节)中,每个 appid 对应的 secret-keydigest-algo 等配置只能通过以下两种方式提供:

  1. application.yml 中静态声明:
    yaml
    sa-token:
      sign-many:
        xm-shop:
          secret-key: 0123456789abcdefg
          digest-algo: md5
  2. 在启动时通过代码一次性注入:
    java
    config.getSignMany().put("xm-shop", new SaSignConfig().setSecretKey("..."));

运行期的验签入口为 SaSignMany.getSignTemplate(appid).checkRequest(...),其底层依赖启动时固化在 SaTokenConfig.signMany 中的 Map<String, SaSignConfig>

二、痛点

在企业级管理系统(SaaS 平台、开放平台、多租户系统、内部微服务网关等)中,接入方应用通常是动态增减的,秘钥也需要定期轮换 / 临时吊销,此时 yaml 静态配置存在明显局限:

维度 yaml 固定配置 企业实际诉求
应用接入 改配置 → 重新打包 / 重启 后台页面新增 appid 即时生效
秘钥轮换 改配置 → 重启 一键轮换,旧秘钥可灰度并存
秘钥吊销 改配置 → 重启 发现泄露立即禁用,无需发版
多环境一致性 各环境各自维护 yaml 统一 DB / 配置中心管理
审计与权限 秘钥明文散落在配置文件 加密存储 + 操作审计日志

简言之:多应用模式的"多"已经支持,但"动态"还不支持,这使得它在真正的多接入方场景下难以落地。

三、建议方向(供讨论,非最终方案)

核心诉求是:SaSignMany.getSignTemplate(appid) 在获取模板时,支持从可扩展的数据源(DB / Redis / 配置中心 / 自定义 SPI)动态解析 SaSignConfig,而不是只读启动时的内存 Map。

可能的设计方向,欢迎大家补充 / 取舍:

方向 A:引入 SaSignConfigProvider SPI(推荐优先讨论)

  • 定义接口,例如:
    java
    public interface SaSignConfigProvider {
        SaSignConfig getConfig(String appid);
        // 可选:列表、刷新、存在性判断
    }
  • 框架提供默认实现(即当前的内存 Map,保持向后兼容);
  • 用户可注入自定义实现,从 DB / Nacos / Apollo 等加载;
  • SaSignMany.getSignTemplate(appid) 内部改为优先走 Provider,未命中再回退内存 Map。

方向 B:在 SaSignConfig 层面支持懒加载 / 回调

  • signMany 的 value 允许是一个 Supplier<SaSignConfig> 或函数式接口,调用时再解析;
  • 改动较小,但表达能力弱于独立 SPI。

方向 C:提供官方 DB 存储 starter

  • 约定表结构(appid、secret_key、digest_algo、status、expire_time 等),开箱即用;
  • 可作为方向 A 的一个官方参考实现。

四、需要一并讨论的关联问题

  1. 缓存策略:每次验签都查 DB 性能不可接受,是否需要内置本地缓存 + TTL?缓存失效 / 主动刷新机制如何设计?
  2. 秘钥热更新:DB 中秘钥变更后,如何让各节点及时生效?是否需要配合事件 / MQ / 配置中心推送?
  3. 多秘钥并存(灰度轮换):同一个 appid 是否允许同时存在 current / previous 两把秘钥,验签时依次尝试?
  4. 应用状态控制:是否支持 enabled 字段,实现不停机禁用某个 appid?
  5. 性能与并发:高并发网关场景下,Provider 实现需要注意什么,框架是否需要提供兜底降级策略?
  6. 向后兼容:现有 yaml + 代码注入方式必须保持可用,新能力应以增量、可选的方式加入。

五、典型应用场景

  • 开放平台:第三方应用在管理后台自助申请 appid / secret,审核通过后写入 DB,立即可调接口;
  • SaaS 多租户:每个租户一套独立秘钥,租户停用即禁用签名;
  • 微服务网关:下游服务清单动态变化,网关侧无需为新增服务改配置重启;
  • 等保 / 合规场景:秘钥必须加密存储在 DB 并支持轮换审计,不能明文落在配置文件。

六、诉求

希望社区和维护者评估:

  1. 该需求是否具有普遍性,是否值得纳入 roadmap;
  2. 上述方向中哪种更符合 Sa-Token 的整体设计哲学(轻量、可扩展、低侵入);
  3. 如果方向可行,期望的最小可用版本(MVP)应包含哪些能力。