Files
Hua.Todo/docs/project/v1.2.0-tasks/06.1-CloudSync-服务端安全设计方案.md
T
2026-04-13 23:10:07 +08:00

7.3 KiB

06.1 - 云同步(安全进阶):服务端账户/凭据与策略实现方案

1. 目标

04-*(基础能力)与 06-*(落盘策略)提供服务端底层安全实现的具体方案,确保账户密码存储、Token 管理、二次认证及安全策略下发具备生产级安全性。

2. 账户与密码安全存储

服务端不应存储明文密码,需采用强哈希算法进行加盐处理。

存储结构 (Users 表)

  • UserId: Guid (主键)
  • UserName: string (唯一索引)
  • PasswordHash: string (存储哈希后的结果)
  • PasswordSalt: string (若哈希算法自带 Salt,如 BCrypt/Argon2,则可省略)
  • Role: string (用户角色,如 admin/user)
  • CreatedAtUtc: DateTime
  • UpdatedAtUtc: DateTime

哈希算法建议

  • 算法: Argon2id (推荐) 或 BCrypt
  • 配置: 迭代次数、内存占用、并行度应符合 OWASP 最新建议。

3. Token 管理 (JWT)

采用 JSON Web Token (JWT) 作为会话凭据,并支持细粒度权限控制。

Token 结构 (Payload)

{
  "sub": "UserId",
  "name": "UserName",
  "role": "Role",
  "perms": ["tasks:read", "sync:write", "policy:read"],
  "iat": 1712000000,
  "exp": 1712003600,
  "iss": "Hua.Todo.Server",
  "aud": "Hua.Todo.Client",
  "isStepUp": false  // 是否通过了二次认证
}

校验逻辑

  • 每次请求需携带 Authorization: Bearer {token}
  • 服务端验证签名、有效期(exp)、签发者(iss)及受众(aud)。
  • 权限校验:中间件检查 perms 声明是否包含当前接口所需的权限。

4. 二次认证与会话提升 (Step-up)

针对高风险操作(如 sync:writepolicy:write),要求会话必须处于“提升状态”。

流程设计

  1. 触发: 客户端调用 /sync,服务端检查 Token 的 isStepUp 声明。
  2. 拒绝: 若 isStepUp == false,返回 403 SECOND_FACTOR_REQUIRED
  3. 挑战: 客户端调用 /auth/step-up,提供二次认证凭据(如再次输入密码,或 TOTP 验证码)。
  4. 提升: 验证成功后,服务端颁发一个新的 Token,其中 isStepUp: true,且有效期较短(如 30 分钟)。
  5. 重试: 客户端携带新 Token 重新发起请求。

5. 安全策略 (Security Policy) 存储与下发

安全策略决定了客户端的“落盘”行为及二次认证频率。

策略定义 (SecurityPolicies 表)

  • Id: int (主键)
  • UserId: Guid (外键)
  • AllowPersist: bool (是否允许客户端持久化任务数据)
  • AllowSync: bool (是否允许该用户同步)
  • SecondFactorExpiryMinutes: int (二次认证状态保持时长,默认 30)
  • IsTrustedDeviceOnly: bool (是否仅限受信任终端)

下发逻辑

  • 客户端通过 GET /security/policy 获取。
  • 策略应与 UserId 绑定,允许管理员针对不同用户/角色进行差异化配置。

6. 审计日志 (Audit Logs)

记录关键安全事件,便于追溯。

  • 登录成功/失败(记录 IP、终端信息)。
  • 高风险操作尝试(是否通过二次认证)。
  • 安全策略变更。

8. 客户端 UI 与交互设计

8.1 二次认证 (Step-up) 交互流程

  1. 静默拦截: 当用户触发高风险操作(如点击“立即同步”且 Token 已过期或未提升)时,客户端拦截请求并检测到 403 SECOND_FACTOR_REQUIRED
  2. 弹出对话框: 弹出“安全验证”模态框。
    • 标题: 需要二次认证。
    • 描述: “为了保护您的数据安全,执行此操作需要验证身份。”
    • 输入: 密码输入框(或 TOTP 验证码输入框)。
    • 操作: [取消] [验证并继续]。
  3. 状态保持: 验证成功后,UI 应显示短暂的“验证成功”提示,并自动重试刚才被拦截的操作。

8.2 客户端 UI (针对普通用户)

在客户端“设置 -> 云同步 -> 安全”路径下:

  • 落盘策略 (AllowPersist):
    • 展示: 状态开关(Toggle)。
    • 交互:
      • 若由服务端强制禁止,开关应为禁用状态(Disabled),并附带说明:“受服务端策略限制,当前终端禁止落盘”。
      • 若允许修改,关闭开关时应弹出强提醒:“关闭后,所有本地任务数据将被立即清除,退出应用后数据将不再保留。确定继续吗?”
  • 二次认证频率:
    • 展示: 显示当前二次认证的有效期(如 30 分钟)。

8.3 “不可落盘”模式下的视觉提示

allowPersist == false 时:

  • 状态栏/标题栏: 增加“无痕模式”或“内存存储”小图标/文字提醒。
  • 登录页: 增加提醒:“当前环境配置为禁止落盘,数据仅在本次运行期间有效”。
  • 退出应用: 点击退出时,若有未同步数据,强提醒:“数据未同步且本地禁止落盘,退出将导致数据丢失。确定退出吗?”

9. 服务端管理后台 (Admin Dashboard)

为了避免直接操作数据库,服务端需提供一套 Web 管理后台,供管理员维护账户、权限与安全策略。

9.1 工程位置与实现

  • 宿主项目: Hua.Todo.Host
  • 实现方式:
    • 前端采用 Vue 3 + Vite 开发。
    • 静态资源在构建后嵌入到 Hua.Todo.Hostwwwroot 目录或作为内嵌资源。
    • 后端通过 ASP.NET Core 的 UseStaticFiles() 托管,并确保 /admin 路由指向前端入口。

9.2 系统初始化 (Bootstrap)

  • 触发条件: 当检测到数据库中无任何用户时,访问 /admin 自动跳转至 /admin/bootstrap
  • 功能: 创建首个“超级管理员”账号。
  • UI: 简单的表单(用户名、密码、确认密码)。

9.3 用户管理 (User Management)

  • 用户列表: 展示所有已注册用户(UserId, UserName, Role, CreatedAt)。
  • 创建用户: 管理员手动添加用户(用于内部系统或受控注册)。
  • 重置密码: 为忘记密码的用户生成临时密码或直接重设(需审计记录)。
  • 禁用/删除: 软删除或禁用账号。

9.4 安全策略配置 (Security Policy Management)

  • 全局策略: 设置系统默认的 allowPersistallowSyncSecondFactorExpiry
  • 单用户覆盖: 在用户详情页中,管理员可以针对特定高风险用户/终端覆盖全局策略(例如:对特定外包人员账号强制 allowPersist = false)。

9.5 会话与凭据管理 (Session Management)

  • 在线会话查看: 展示当前所有有效的 Token/会话(记录 IP、最后活跃时间、是否已提升权限)。
  • 强制下线 (Revoke): 管理员可一键吊销特定用户的所有 Token(将其加入黑名单)。

9.6 审计日志查看器 (Audit Log Viewer)

  • 过滤查询: 按时间、用户、事件类型(登录、同步、策略变更)过滤。
  • 高亮显示: 对“二次认证失败”、“异常 IP 登录”等敏感事件进行红色高亮。

10. 约束与风险

  • Token 吊销: 默认 JWT 是无状态的。若需支持强制下线,需引入 Redis/DB 黑名单。
  • HTTPS: 所有安全通信必须基于 TLS,防止中间人攻击窃取 Token。
  • 暴力破解: 需在 POST /auth/login 接口增加限流(Rate Limiting)机制。