proposal.md 3.4 KB

状态(2026-04-18 立项):提案阶段,未实施 优先级:高(Phase B.2 基座安全增强,早于 mjava-com 专项)

Why

mjava 基座当前 API 安全裸奔:

  • 无统一鉴权:任何知道 URL 的调用方都能直接访问任意 Controller(filter/RequestFilterRequestInterceptor 当前只打日志,不做任何校验)
  • 无防重放保护:即便将来加签名,不带时间窗 + Nonce 的话攻击者仍可抓包重放
  • 客户子项目各自重造:mjava-guangming 的 SSO 校验、mjava-shunfeng 的 dingtalk webhook 校验各自实现,代码不共享

需要在基座提供可选启用的"请求鉴权 + 防重放"统一能力。默认关闭(保护现有 mcli/shunfeng/guangming 生产服务不中断),子项目按需开启;mjava-com 未来的调用方签名也将复用本能力,避免重复建设。

add-observability-foundation 的 TraceId 互补:前者负责"日志可追溯",本 change 负责"调用不可伪造"。

What Changes

新增 3 个基座组件(全部放在 mjava/,子项目零代码改动即可通过配置启用):

  • com.malk.filter.AuthFilter:请求进入时校验 token/signature + 时间窗 + Nonce 去重;失败返回 401/403
  • com.malk.utils.UtilSignature:HMAC-SHA256 签名计算与验证工具类
  • com.malk.core.NonceCache:基于 UtilToken.TimedCache 的 Nonce 去重缓存(封装 namespace + TTL = 时间窗)

配置开关:

mjava:
  auth:
    enabled: false           # 默认关闭;子项目可按需打开
    secret: ${AUTH_SECRET}   # 服务端共享密钥(环境变量注入)
    window: 300              # 时间窗秒数,默认 5 分钟
    nonce-cache-size: 10000  # Nonce 缓存条目上限(LRU 淘汰)
    exempt-paths:            # 豁免路径清单(正则或 Ant 风格)
      - /actuator/**         # 健康检查
      - /api/*/callback/**   # 第三方 webhook 回调(自带签名协议)

另加 @NoAuth 注解,方法/类级别显式豁免。

Capabilities

New Capabilities

  • request-auth:基于 HMAC-SHA256 + 共享密钥的统一请求鉴权
  • replay-guard:基于时间窗 + Nonce 的防重放保护

Modified Capabilities

Impact

  • 新增文件AuthFilter.java / UtilSignature.java / NonceCache.java / AuthConfig.java / @NoAuth 注解 / AuthConfigProperties.java
  • 不动RequestFilter / RequestInterceptor / CatchException 原职责
  • ymlapplication.yml 新增 mjava.auth.* 结构,默认 enabled: false
  • 对 mcli / shunfeng / guangming:零影响(enabled: false 默认不拦截)
  • 对 mjava-com:未来的调用方鉴权直接用本 UtilSignature + NonceCache;mjava-com 的 CallerAuthInterceptor 设计可简化

Non-Goals

  • ❌ 不做 OAuth2 / OpenID Connect(重量级,不适合内部场景)
  • ❌ 不做 JWT 签发与刷新流程(当前是无状态 HMAC,够用;将来如需再单独提案)
  • ❌ 不做 mTLS(网络层配置由运维侧处理)
  • ❌ 不取代第三方 webhook 回调的供应商签名校验(钉钉 DingCallbackCrypto / 宜搭 token 验证等各自保留)
  • ❌ 不做角色/权限(RBAC/ABAC),只解决"是谁 + 请求是否合法 + 是否重放"三件事
  • ❌ 本 change 不强制要求任何现存客户升级开启