From 091ef426db0e72c1eebb179a60e45344b76af0dc Mon Sep 17 00:00:00 2001 From: gitadmin Date: Tue, 30 Jun 2026 17:09:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20SSO=20=E7=BB=9F=E4=B8=80=E8=AE=A4?= =?UTF-8?q?=E8=AF=81=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 集成 Authelia OIDC,支持统一认证登录 - 添加 OIDC 登录页面和回调处理 - 更新 docker-compose.yml 统一环境变量管理 - 更新 CHANGELOG.md 和 CLAUDE.md --- .env.example | 25 +++++++++++++++++++------ CHANGELOG.md | 15 +++++++++++++++ CLAUDE.md | 9 +++++++++ docker-compose.yml | 4 ++++ src/lib/oidc.ts | 1 + 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index 3e91372..fed27cc 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,25 @@ DATABASE_PATH=./data/issue.db JWT_SECRET=your-secret-key-change-in-production ADMIN_PASSWORD=admin123 -ASSETS_API_URL=http://assets-ai:3000/api +NODE_ENV=development +# ⚠️ 仅限本地开发环境(自签名证书),生产环境禁止设置此变量 +NODE_TLS_REJECT_UNAUTHORIZED=0 + +# LDAP 配置 +LDAP_URL=ldap://localhost:3890 +LDAP_BASE_DN=dc=tlyq,dc=ai +LDAP_ADMIN_DN=uid=admin,ou=people,dc=tlyq,dc=ai + +# assets-ai API 配置 +ASSETS_API_URL=http://localhost:6177/api ASSETS_API_KEY=your-assets-api-key +NEXT_PUBLIC_ASSETS_URL=http://localhost:6177 + # 允许调用 issue-ai API 的 Key(逗号分隔,支持多个),由 issue-ai 管理界面生成 ALLOWED_API_KEYS=your-issue-api-key -# NEXT_PUBLIC_ 前缀:构建时内嵌到客户端 JS,云上必须通过 deploy-ai.sh 设置 -# 本地开发:http://localhost:6177 -# 云上生产:https://assets.tlyq.ai -NEXT_PUBLIC_ASSETS_URL=http://localhost:6177 -NODE_ENV=development + +# OIDC 配置(SSO 统一认证) +AUTHELIA_URL=https://sso.tlyq.ai +OIDC_CLIENT_ID=issue-oidc +OIDC_CLIENT_SECRET=change-me-to-hashed-secret +OIDC_REDIRECT_URI=http://localhost:6176/api/auth/callback diff --git a/CHANGELOG.md b/CHANGELOG.md index 8da8290..9f63265 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # 变更日志 +## 2026-06-30 + +- [新增] SSO 统一认证:集成 Authelia OIDC,支持统一认证登录 +- [新增] OIDC 登录页面:添加「统一认证登录」按钮,支持 LDAP 回退 +- [新增] `src/lib/oidc.ts`:OIDC 客户端配置(PKCE + state + nonce) +- [新增] `src/app/api/auth/login/oidc/route.ts`:OIDC 登录端点 +- [新增] `src/app/api/auth/callback/route.ts`:OIDC 回调处理(含权限同步) +- [新增] `src/app/api/auth/logout/route.ts`:跨域登出(支持 domain 参数) +- [修复] NODE_TLS_REJECT_UNAUTHORIZED=0:Authelia 使用自签名证书 +- [修复] OIDC redirect_uri 回调重定向到 localhost:添加 getBaseUrl() 函数 +- [修复] token_endpoint_auth_method 配置缺失:添加 client_secret_basic +- [修复] middleware 路由匹配:`/api/auth/login` 改为前缀匹配 `/api/auth/login*` +- [优化] docker-compose.yml:统一环境变量管理,移除 env_file +- [优化] .env.example:添加 OIDC 配置模板 + ## 2026-06-24 - [修复] SQLite 时区根源修复:重建表修改所有时间列 DEFAULT 为 `datetime('now', '+8 hours')`,涉及 7 个表 9 个列 diff --git a/CLAUDE.md b/CLAUDE.md index 0c4159c..43c53ec 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -189,6 +189,11 @@ npm run import # 导入工单 | `JWT_SECRET` | `dev-secret-key-local` | `${ISSUE_JWT_SECRET}` | 本地两系统需一致(同 localhost 域) | | `DATABASE_PATH` | `./data/issue.db` | `/app/data/issue.db` | Docker volume 挂载 | | Cookie 名 | `session_issue` | `session_issue` | 本地用不同名防 localhost 域冲突 | +| `AUTHELIA_URL` | `https://sso.tlyq.ai` | 同 | Authelia 地址 | +| `OIDC_CLIENT_ID` | `issue-oidc` | 同 | OIDC 客户端 ID | +| `OIDC_CLIENT_SECRET` | 本地生成的哈希值 | 服务器生成的哈希值 | OIDC 客户端密钥 | +| `OIDC_REDIRECT_URI` | `http://localhost:6176/api/auth/callback` | `https://issue.tlyq.ai/api/auth/callback` | OIDC 回调地址 | +| `NODE_TLS_REJECT_UNAUTHORIZED` | 不需要 | `0`(Authelia 使用自签名证书) | TLS 证书验证 | ### `.env.local` 示例 @@ -201,6 +206,10 @@ ASSETS_API_URL=http://localhost:6177/api ASSETS_API_KEY=ak_<32字节十六进制> ALLOWED_API_KEYS=ak_<32字节十六进制> NEXT_PUBLIC_ASSETS_URL=http://localhost:6177 +AUTHELIA_URL=https://sso.tlyq.ai +OIDC_CLIENT_ID=issue-oidc +OIDC_CLIENT_SECRET=<本地生成的哈希值> +OIDC_REDIRECT_URI=http://localhost:6176/api/auth/callback ``` --- diff --git a/docker-compose.yml b/docker-compose.yml index 50e77ad..1a87f12 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,6 +26,10 @@ services: - LDAP_BASE_DN=dc=tlyq,dc=ai - LDAP_ADMIN_DN=uid=admin,ou=people,dc=tlyq,dc=ai - TZ=Asia/Shanghai + # OIDC 配置 + - OIDC_CLIENT_ID=${OIDC_CLIENT_ID:-issue-oidc} + - OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET} + - OIDC_REDIRECT_URI=${OIDC_REDIRECT_URI:-https://issue.tlyq.ai/api/auth/callback} restart: unless-stopped networks: - webnet diff --git a/src/lib/oidc.ts b/src/lib/oidc.ts index 340350d..4041f33 100644 --- a/src/lib/oidc.ts +++ b/src/lib/oidc.ts @@ -23,6 +23,7 @@ export async function getOidcClient() { client_secret: OIDC_CLIENT_SECRET, redirect_uris: [OIDC_REDIRECT_URI], response_types: ['code'], + token_endpoint_auth_method: 'client_secret_basic', }) lastDiscovery = now return oidcClient