基础平台技术研究¶
输入为正式鉴权规格、后台规格、宪法。前端框架已批准,后端选择已于本轮确认采用,保留原推断出处与替代方案供追溯。
R1:后端版本与运行时¶
- Decision:[APPROVED,原 INFERRED] Spring Boot 3.5.16、JDK 21 LTS、Maven 3.9.x;Spring Security、Spring Data 和 Spring Session 由 Boot BOM 管理,不手动拼接最新主版本。
- Rationale:Maven Central 的 3.x 稳定版本列表和官方 3.5 文档均指向 3.5.16;本机已有 JDK 21.0.11、Maven 3.9.16。官方系统要求允许 Java 17—25;选已有 LTS 减少环境变更。[O1][O2]
- Alternatives:Boot 4.x 虽是另一稳定主线,但超出宪法限定,不采用;JDK 25 LTS 可用,但当前没有需更高语言版本的需求,增加环境成本;Java 17 是支持下限,但本机与目标建议已使用 21,不额外回退。
- Evidence:2026-10-29 查询的 Maven 元数据快照见
evidence/boot-metadata.xml;这不是已生成 pom 或已编译后端的证明。
R2:关系数据与持久化¶
- Decision:[APPROVED,原 INFERRED] PostgreSQL 18.x(本轮官方当前小版本 18.6)、Spring Data JPA、Boot 管理的 PostgreSQL 驱动、Flyway 及 PostgreSQL 数据库适配模块;项目迁移是唯一建表路径,关闭运行时自动改表。
- Rationale:账户唯一性、角色关系、并发恢复保护和会话需要事务;一个数据库承载全部基础平台状态。Spring 官方支持该关系型访问路径;PostgreSQL 18 处于支持期。[O3][O4]
- Alternatives:MySQL 同样可用,但当前无既有数据兼容要求,不同时保留两套方言;H2 不作为验收库,避免用不同锁与约束语义证明并发正确;直接 JDBC 可行,但需额外维护基础映射与分页,不比现成 JPA 简单。
- Boundary:数据模型文件不写 DDL。迁移、约束、索引和实际镜像 tag/digest 在工程任务中实现并锁定。JPA 使用乐观版本与必要悲观锁,不引入额外分布式锁。
R3:身份与会话¶
- Decision:[APPROVED,原 INFERRED] Spring Security 承担认证;Spring Session JDBC 持久化 HttpSession,与业务共用 PostgreSQL;浏览器仅携带不透明 HttpOnly 会话 Cookie。使用 Boot 3.5 支持的
spring-session-jdbc,不照抄 Boot 4 新 starter 名称。[O5] - Rationale:退出与全部会话撤销需要服务端控制,单机无需再部署 Redis;不新增前端身份服务。会话创建、ID 轮换、上下文保存与存储均使用框架。[O6]
- Alternatives:自行签发 JWT 需要另加撤销体系,不适合当前行为;Redis 会话成熟但多一个运行组件;纯容器内存会话最少依赖,但对持久化、检索与重启行为的验证不如统一 JDBC 明确。
- Policy adapter:8 小时绝对期限、只按有效业务操作更新的 30 分钟空闲期限、账户/角色版本失效检查由薄策略适配实现,不能自研会话存储。框架默认每请求续期不能直接证明符合 FR-006;细节见 Plan。
- Revocation:账户状态/角色/密码改变时递增账户认证版本;角色权限改变时递增角色授权版本。每次受保护请求比对数据库当前版本与登录快照,不依赖物理删除会话行的时机;失配立即拒绝并作废本次会话。删除/清理记录只负责回收,不能作为唯一撤权依据。
R4:密码与浏览器安全¶
- Decision:[APPROVED,原 INFERRED] 使用 Spring Security 的 DelegatingPasswordEncoder,写入算法选择框架 PBKDF2 v5_8 配置;新密码保留原字符,不裁剪、不静默截断;12—64 个 Unicode 码点。通过标准 CSRF 机制保护所有变更,包括注册、登录和退出。[O7][O8]
- Rationale:满足已批准字符上限且不新增密码算法依赖;密码编码参数在目标环境验证成本。会话 Cookie 生产使用 Secure、HttpOnly、SameSite=Lax、Path=/、不设置 Domain。
- Alternatives:默认 bcrypt 有输入字节长度约束,不能把 64 字符误当 64 字节;Argon2 可用,但当前框架实现所需额外依赖与调参没有已批准的必要性;自研散列或明文存储不满足框架优先与安全目标。
- CSRF adapter:使用 HttpSessionCsrfTokenRepository;公开 GET
/api/v1/csrf-tokens返回框架给出的 token/headerName,前端仅保留在内存。认证成功后重新取 token,退出后如需重试也重新取。Cookie 的 HttpOnly 不妨碍读取独立 CSRF 响应。 - Unknown/disabled:对不存在或禁用用户使用相同失败文案;未知用户走框架虚拟密码核实路径,不承诺绝对恒定响应时间。失败计数对已知与未知合法登录名一致,存储与并发规则见 data-model。
R5:同源网络与界面状态¶
- Decision:[APPROVED,原 INFERRED] 浏览器同源访问
/api/v1/,开发用 Next.js 纯转发,部署由 infra 的入口转发到 core;web 不建立业务 BFF、不代理生成身份、不落库。管理界面使用客户端资源组件,先核实身份再展示敏感内容。 - Rationale:减少凭证跨域配置;前端只有传输适配与状态展示,实际权限始终由 core 决定。受保护数据
no-store,禁用资源后台轮询、焦点自动刷新和断线自动重取,避免后台活动续空闲时间。 - Alternatives:前后端跨源部署需要额外 CORS/凭证边界配置,当前不采用;Next.js 内实现登录数据库会违反分层;长期将会话凭证放入浏览器持久化存储不符合本次会话设计。
- Provider mapping:Refine 的 list/show/create/edit/delete 动作与 core 返回的展示许可直接映射;账户“禁用/重置/分配角色”等自定义动作按契约键读取,不在 web 编写角色到权限规则。CanAccess 等保护展示,不能替代服务端请求授权。
R6:并发与恢复¶
- Decision:[APPROVED,原 INFERRED] 所有角色绑定、角色权限、账户启用/角色变更及初始化在数据库事务中核实当前操作者和目标。使用同一条预置治理锁记录串行化这些低频管理变更,固定“治理锁→角色→账户”锁顺序;资源版本拒绝过期编辑。
- Rationale:最后管理员与角色删除/分配是跨行不变量,仅锁被修改的不同账户不足以避免同时禁用最后两位管理员。MVP 管理写入量低,单个锁概念最少。
- Alternatives:只依赖查询后计数存在并发竞态;仅乐观锁各自目标行无法保护跨账户约束;分布式锁增加组件且不改善同数据库事务的一致性。
- Boundary:不锁所有列表读取;未完成的在途操作可以按其入场版本完成,变更提交后新入场操作必须读到新版本。自定义管理策略是已批准业务规则的框架事务适配,不是通用权限引擎。
R7:依赖与批准状态¶
- 前端依赖采用已由 ADR-001 接受,实验组合记录于兼容报告(本地资料,未发布)。
- 后端持久化、会话和密码适配选择记录于拟议 ADR-002,状态 Accepted,2026-10-29 用户确认技术方案并授权继续实现。
- 不引入 Redis、OAuth 服务、通用策略引擎、事件总线、审计增强或实验业务模块。
官方来源(2026-10-29 核查)¶
- O1:Boot 3.5 系统要求。
- O2:Maven Central Boot parent 元数据。
- O3:Boot 3.5 SQL 支持。
- O4:PostgreSQL 版本支持表。
- O5:Boot 3.5 Spring Session 自动配置。
- O6:Spring Security 6.5 会话管理。
- O7:Spring Security 6.5 密码存储。
- O8:Spring Security 6.5 CSRF。
- O9:Boot 3.5 管理依赖坐标。
以上可变在线页面不代替未来构建锁定;对官方机制的引用不等于本项目已完成后端测试。