# SSO 统一登录鉴权服务设计(sso.beexofficial.com)

整理日期:2026-06-16　|　代码:**独立仓库 `beex-sso`**(github.com/chaokongzwp/beex-sso,已建并 push)


## 一句话

把"飞书登录发证"从 admin 业务服务里抽出来,做成**全局唯一**的轻量服务 `sso.beexofficial.com`,服务 admin 各环境前端 + prd 文档站;业务服务只负责**校验** session。按 jar + systemd 部署,**不走 Docker**。


## 为什么这么做


- 登录本就是**跨环境、跨应用**的集中能力(admin 全环境 + prd 共用一个 `AUTH_API`),却寄生在 `admin-api-id-test` 业务服务里 —— 等于生产登录依赖测试服务活着,是耦合 + 可用性的坑

- 抽出来后:发证一处、各服务校验同一 Redis session,职责清爽,也是上线要补的 P0 鉴权的自然归宿


## 为什么不用 Docker


- 现有两个服务(core / admin)都是 **jar + systemd** 直接部署,整个工程没有任何 Docker

- SSO 保持一致:少一层镜像构建/仓库/运行时,运维统一。它是个无状态 Java 服务,systemd 足够,Docker 没有额外收益


## 架构:发证 vs 校验


- **SSO 服务(发证)** —— 本服务

    - 飞书 OAuth:`/login`(跳授权页)、`/callback`(换 token、校验组织、建 session)、`/verify`(校验)

    - session 存 Redis,生命周期归它管

- **业务服务(校验)** —— core / admin

    - 各自的拦截器校验 session:读同一 Redis(`bx:prd:session:*`)或调 SSO 的 `/verify`

    - admin 现已有 `AdminApiAuthInterceptor`(`/api/v1/admin/**` 强制校验),正好复用这个模式

- **共享点 = Redis session 存储**:SSO 写、业务服务读,key 前缀 `bx:prd:session:*` 全链路一致


## 命名规则(本服务确立,后续按此扩展)


| 维度 | 规则 | 本服务取值 |
|---|---|---|
| git 仓库 | 独立部署边界优先使用独立仓库 | **`beex-sso`（独立仓库，不在 `beex-service` 里）** |
| 启动类 | `SeahubX{角色}Application` | `SeahubXSsoApplication` |
| 包名 | `com.seahub.x.{角色}` | `com.seahub.x.sso` |
| 域名 | `{服务}-{国}-{env}` ,**但 SSO 是全局例外**(登录=组织级,与环境无关) | `sso.beexofficial.com`(无 env 后缀) |
| 端口 | 7002 core / 7003 admin / 依次 | `7004` |
| systemd 服务名 | `seahub-x-{角色}-service` | `seahub-x-sso-service` |
| Redis key | `bx:prd:session:*`(session)、`bx:prd:oauth:state:*`(state) | 保持一致,便于切换期互通 |
| env 变量 | `SEAHUB_{大写}` | `SEAHUB_SSO_PORT` / `SEAHUB_FEISHU_OAUTH_*` / `SEAHUB_REDIS_*` |
| 云效流水线 | `beex-{角色}-service` | `beex-sso-service` |


> 关键约定:SSO 是**全局唯一**服务,**不按环境拆**(不叫 sso-id-test)。因为飞书登录只验"是不是本组织成员",与 id/my、test/prod 无关。各环境业务服务都向同一个 SSO 校验。


## 代码结构(已建)


独立仓库，**自包含、不依赖 `beex-service` 内的 `seahub-core`**（Spring Boot 3.4.5 standalone parent）：

- `pom.xml` —— spring-boot 独立 parent + web + data-redis + actuator;无 seahub-core、无 sdk-mybatis(不碰 DB)

- `src/main/java/com/seahub/x/sso/`

    - `SeahubXSsoApplication.java` —— 启动类(默认扫本包)

    - `config/FeishuAppProperties.java` —— 内联的飞书 app 配置(`seahub.feishu.bot.app-id/secret`),不再引 core

    - `config/CorsConfig.java` —— 自带一份(放行 `/admin/auth/**` → `*.beexofficial.com`)

    - `auth/FeishuOAuthService.java` —— OAuth 发证 + session(Redis)

    - `auth/FeishuOAuthProperties.java` —— `seahub.feishu.oauth.*` 配置

    - `auth/FeishuUserInfo.java` —— 用户信息 record

    - `controller/SsoFeishuOAuthController.java` —— `/admin/auth/feishu/{login,callback,verify}`

- `src/main/resources/application.properties` —— 端口/飞书/Redis/actuator 配置

- jar:`mvn -DskipTests package` → `target/seahub-x-sso.jar`(finalName 固定,无版本后缀)


> 路径保留 `/admin/auth/feishu/**`:前端切到本服务只需把 `AUTH_API` 域名改成 `sso.beexofficial.com`,**不用改路径**。


## 部署(jar + systemd,不走 Docker)


- on-host:`ci/deploy-sso-service.sh` —— 解包 jar → 维护 `/opt/seahub-x-sso-service/.env` → systemd 重启 → 健康检查 `:7004/actuator/health`

- 编排:`ci/deploy-sso-service-ssh.sh` —— 云效容器里构建 jar → 打包 → scp 到 ECS → 远端跑 on-host 脚本

- 流水线:`ci/yunxiao-sso-service-pipeline.yml`(`beex-sso-service`,手动触发)

    - 需配密钥变量:`SEAHUB_SSO_ECS_HOST/USER/PASSWORD`、`SEAHUB_LARK_WEBHOOK_*`

- 机器:先复用 admin ECS(同机 7004),**生产建议独立机器**(改 `SEAHUB_SSO_ECS_*`)

- 证书:`sso.beexofficial.com` 用 `ci/cdn-cert-renew.sh` / `setup-admin-cert-renewal.sh` 传该域名各跑一次(或网关统一证书)


## 必填配置


- `SEAHUB_FEISHU_BOT_APP_ID` / `SEAHUB_FEISHU_BOT_APP_SECRET` —— 飞书 app(与 bot 同一套)

- `SEAHUB_FEISHU_OAUTH_TENANT_KEY` —— 组织校验

- `SEAHUB_REDIS_HOST` / `SEAHUB_REDIS_PASSWORD` —— session 存储

- 飞书开放平台:重定向 URL 加 `https://sso.beexofficial.com/admin/auth/feishu/callback`


## 上线分两步(安全切换)


- **阶段 1(现在,已就绪):并存**

    - SSO 服务独立跑起来,与 admin 共用同一 Redis + 同 session key → SSO 签发的 session,admin 拦截器能直接校验

    - admin 暂时不动(它内嵌的登录还在),零风险

- **阶段 2(切换):集中**

    - 前端 `AUTH_API` 改指 `sso.beexofficial.com`(admin 各环境 + prd)

    - admin 业务服务移除内嵌登录,只保留校验拦截器(读同一 Redis 或调 SSO `/verify`)

    - admin **删掉**自己内嵌的登录代码(`AdminFeishuOAuthController` + `FeishuOAuthService` 的发证部分),只留校验拦截器 —— 重复自然消失(SSO 独立仓库,不与 admin 共享代码,故不走"下沉 core",而是 admin 退掉发证)


## 待办


- 代码侧:SSO 是独立仓库、自包含;与 admin 的发证逻辑暂时并存(零风险),阶段 2 由 admin 退掉发证消除重复

- 基建:开 SSO 机器(或先用 admin 机)、配 `sso.beexofficial.com` DNS + 证书 + 飞书回调白名单、云效建 `beex-sso-service` 流水线

- 授权粒度:现在只验"组织成员",生产操作(改分佣/提现)以后宜加角色/权限,可放本服务做
