# SDD-009:飞书认证会话身份 | 字段 | 内容 | |---|---| | 版本 / 变更级别 | 0.1 / S3 | | 设计状态 | 已形成 | | 实现状态 | 未开始 | | 负责人 / 日期 | Codex / 2026-10-22 | | 关联需求 | 飞书登录后在线会话与连接审计显示具体用户 | | 批准状态 | 用户授权排查修复;尚未发布 | ## 1. 背景、目标与范围 线上 2.3.0 认证组件日志显示授权成功且 sub 非空,但 user_username 为空;OpenVPN 状态中 CN、Username 均为 UNDEF。`identityprovider/handlers.go` 已从飞书 user_info 获取 tenant_key、open_id、name,现有短期 grant 未形成持久姓名关联。`openvpn/oidc.go` 没有配置用户名表达式。 目标:内置飞书专线以已验证的 sub 传递用户身份,并展示飞书姓名。保留外部 OIDC、密码、证书模式和现有用户权限;不按 IP 或时间推断历史身份,不自动创建或授权 VPNUser,不查询整个企业通讯录。 ## 2. 需求与约束 - FR-01:内置飞书认证组件使用 token.claims.sub 作为用户名来源,外部配置保持原行为。 - FR-02:仅成功获取飞书资料并通过企业校验后,保存应用、issuer、subject、姓名和更新时间;不保存上游访问令牌。 - FR-03:在线会话与连接审计以稳定 subject 为身份,额外展示同应用同 issuer 的飞书姓名。未知身份保持未知;同名用户不合并。 - NFR-01:姓名仅用于展示,不参与权限判断;资料写入失败时不发放本次授权码;已有记录不回填猜测身份。 ## 3. 架构与方案 回调校验企业后 upsert 独立身份资料表;内置专线生成明确 CEL 用户名表达式。会话采集按当前内置配置及 subject 查资料,保存展示姓名快照;连接审计同步保存姓名快照。前端显示姓名与稳定标识,旧 UNDEF 显示未知。 ## 4. 接口、数据与配置契约 新增身份资料表,issuer、app_id、subject 为联合唯一键;VPNSession 与 ConnectionLog 增加可选 display_name。现有 username 字段语义不变。自动迁移仅新增表与列。内置组件配置增加 oauth2.openvpn-username,要求支持该选项(线上 2.3.0 已通过 --help 核对);外部 OIDC 不增加此配置。 ## 5. 风险与验收 | 风险 | 防护 / 恢复 | 可观察信号 | |---|---|---| | 姓名或应用混淆 | 同 issuer、应用、subject 精确查询;姓名非身份键 | 同名、跨应用测试 | | 新组件配置不兼容 | 发布前核对组件参数,恢复原配置 | 启动日志与监听 | | 旧连接仍无身份 | 用户重新发起 WebAuth;不关联旧 UNDEF | 状态文件用户名 | | 数据写入失败 | 本次回调 503,不发码 | 负向测试 | | AC | 对应需求 | 操作与预期 | 验证方式 | 结果 | |---|---|---|---|---| | AC-01 | FR-01 | 内置生成 sub 表达式,外部不改变 | Go 测试 | 未执行 | | AC-02 | FR-02、NFR-01 | 保存及更新同一身份,应用隔离;不保存令牌 | Go 测试 | 未执行 | | AC-03 | FR-03 | 会话与审计保留 subject 并显示姓名,未知无误归属 | Go 测试、前端构建 | 未执行 | | AC-04 | FR-01、FR-03 | 真实用户重连后状态用户名非 UNDEF,后台显示姓名 | 远程联调 | 未执行 | ## 6. 发布与恢复 先完成测试及前端构建,备份旧二进制及认证配置,再更新管理二进制;不覆盖数据库或密钥。认证配置在专线下次启动时生成;现有连接不自动中断,重启测试专线须明确告知影响。验证健康、认证监听、实际重连和会话展示。失败恢复旧二进制、旧认证配置及原启动方式;新增表列可保留,旧版忽略,不做删除迁移。没有不可逆删除。 ## 7. 待决问题 真实用户重连需用户本人完成飞书认证;不阻塞本地实现,阻塞端到端验收。历史 UNDEF 无可信身份关联,保持原始记录。