# 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) ```json { "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:write`、`policy: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](file:///d:/Proj/6.Hua.Todo/src/Hua.Todo.Host) - **实现方式**: - 前端采用 **Vue 3 + Vite** 开发。 - 静态资源在构建后嵌入到 `Hua.Todo.Host` 的 `wwwroot` 目录或作为内嵌资源。 - 后端通过 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) - **全局策略**: 设置系统默认的 `allowPersist`、`allowSync` 及 `SecondFactorExpiry`。 - **单用户覆盖**: 在用户详情页中,管理员可以针对特定高风险用户/终端覆盖全局策略(例如:对特定外包人员账号强制 `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)机制。