From 5800d4ddbbc5b54d2de6c9803c6143bac5ab5706 Mon Sep 17 00:00:00 2001 From: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> Date: Fri, 18 Sep 2026 15:39:53 +0800 Subject: [PATCH] docs(auth): document the provider adapter contract and Feishu operator setup AGENTS.md and CONTRIBUTING.md both require docs updates when auth flows or deployment config change; this batch changed both and touched no docs. 03-authentication-design.md described adding a provider as "branch on registrationId inside CustomOAuth2UserService", which the ProviderOAuth2UserService strategy supersedes. Rewrites that recipe: register an OAuthClaimsExtractor bean per provider, add a ProviderOAuth2UserService only when the userinfo response is non-standard, and note that the login page needs no code change. Also records the provider-side obligations that are easy to get wrong -- stable subject with no fallback, emailVerified only on proven ownership, bounded remote calls, no subject in logs -- and un-comments the config example, which still listed GitLab as a future possibility. faq.md told operators to delete "the github and gitlab blocks" to hide SSO buttons. That advice was already incomplete and gets worse per provider, so it now explains the config-driven mechanism: an empty client id keeps the entry off the login page, no file edit needed. 09-deployment.md listed only the GitHub credentials. Adds GitLab and Feishu, and flags a deployment trap: Feishu emails are admin-imported so emailVerified is always false, and skillhub.access-policy.mode=EMAIL_DOMAIN denies every unverified email, which would reject all Feishu logins. Squares the Feishu logo viewBox. It was 407.87x324.19 while login-button renders it in a square w-5 h-5 box, so the mark was distorted. Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> --- .env.release.example | 4 ++++ docs/03-authentication-design.md | 37 ++++++++++++++++++++++++-------- docs/09-deployment.md | 11 +++++++++- docs/skillhub/en/faq.md | 9 ++++++-- docs/skillhub/faq.md | 12 +++++++++-- web/public/feishu-logo.svg | 2 +- 6 files changed, 60 insertions(+), 15 deletions(-) diff --git a/.env.release.example b/.env.release.example index f11c0eb2..cee00087 100644 --- a/.env.release.example +++ b/.env.release.example @@ -122,6 +122,10 @@ OAUTH2_GITLAB_DISPLAY_NAME=GitLab # contact:user.email:readonly on the Feishu open-platform app itself; scopes are not sent here. # Set OAUTH2_FEISHU_AUTHORIZE_URI/OAUTH2_FEISHU_BASE_URI to the Lark endpoints for # international tenants (open.larksuite.com). +# Feishu emails are admin-imported and never confirmed with the user, so emailVerified is always +# false. If you set skillhub.access-policy.mode=EMAIL_DOMAIN in application.yml, that policy +# denies every unverified email and Feishu login will always fail; keep the default OPEN mode, +# or use another policy, when enabling this provider. OAUTH2_FEISHU_CLIENT_ID= OAUTH2_FEISHU_CLIENT_SECRET= OAUTH2_FEISHU_AUTHORIZE_URI=https://accounts.feishu.cn diff --git a/docs/03-authentication-design.md b/docs/03-authentication-design.md index 4c8ef11e..c8735b63 100644 --- a/docs/03-authentication-design.md +++ b/docs/03-authentication-design.md @@ -271,18 +271,37 @@ spring: client-id: ${OAUTH2_GITHUB_CLIENT_ID} client-secret: ${OAUTH2_GITHUB_CLIENT_SECRET} scope: read:user,user:email - # 二期扩展示例: - # gitlab: - # client-id: ... - # authorization-grant-type: authorization_code - # google: - # client-id: ... + gitlab: + client-id: ${OAUTH2_GITLAB_CLIENT_ID} + client-secret: ${OAUTH2_GITLAB_CLIENT_SECRET} + authorization-grant-type: authorization_code + feishu: + client-id: ${OAUTH2_FEISHU_CLIENT_ID} + client-secret: ${OAUTH2_FEISHU_CLIENT_SECRET} + # 飞书的 scope 配在开放平台应用上,不在这里传 + client-authentication-method: client_secret_post + authorization-grant-type: authorization_code ``` Spring Security OAuth2 Client 原生支持多 Provider 并存,新增 Provider 只需: -1. `application.yml` 添加 registration 配置 -2. `CustomOAuth2UserService` 中按 `registrationId` 分支处理用户属性映射 -3. 前端登录页增加对应按钮(通过 `/api/v1/auth/providers` 自动发现) +1. `application.yml` 添加 registration 与 provider 配置 +2. 实现一个 `OAuthClaimsExtractor`,把该 Provider 的属性映射成统一的 `OAuthClaims` +3. 登录页无需改代码:`/api/v1/auth/methods` 只返回配置了真实 client id 的注册, + 图标按 provider 名解析为 `/{provider}-logo.svg` + +第 2 步是按 Provider 注册一个 Bean,而不是在某个类里按 `registrationId` 分支。 +账号匹配、建号、资料权威和账号守卫都在 `OAuthClaims` 之后共享,Provider 自己不做这些决策。 + +如果该 Provider 的 userinfo 响应不是标准的扁平结构(例如飞书用 +`{code, msg, data}` 信封,且以 HTTP 200 返回错误),再额外实现一个 +`ProviderOAuth2UserService`:它声明自己负责哪个 `registrationId`, +接管 userinfo 的加载步骤,其余流程不变。该覆盖运行在 +`RemoteIdentityIoExecutor` 边界内,因此 Provider 的 HTTP 调用不会持有数据库事务。 + +Provider 侧还需遵守:subject 必须稳定(不要用可能在两次登录间变化的字段做 +fallback,否则同一个人会被拆成两个平台账号)、只有在 Provider 真正证明了邮箱 +所有权时才置 `emailVerified=true`、远程调用要有超时与响应大小上限、 +claims 提取过程不记录 subject/email/token。 ## 4. 核心接口设计 diff --git a/docs/09-deployment.md b/docs/09-deployment.md index 2bbf6c8c..3671c94d 100644 --- a/docs/09-deployment.md +++ b/docs/09-deployment.md @@ -283,7 +283,16 @@ services: - `SKILLHUB_WEB_API_BASE_URL=/skillhub` - `SKILLHUB_PUBLIC_BASE_URL=https://example.com/skillhub` 网关可以在转发到 Web 容器前将该前缀重写掉,但公网 URL 仍必须保留前缀,确保 OAuth、CLI 和 registry 链接正确。 -- 如果要开放真实登录,再补充 `OAUTH2_GITHUB_CLIENT_ID` / `OAUTH2_GITHUB_CLIENT_SECRET` +- 如果要开放真实登录,再补充对应 Provider 的 client id/secret: + - GitHub:`OAUTH2_GITHUB_CLIENT_ID` / `OAUTH2_GITHUB_CLIENT_SECRET` + - GitLab:`OAUTH2_GITLAB_CLIENT_ID` / `OAUTH2_GITLAB_CLIENT_SECRET`(自建实例再设 `OAUTH2_GITLAB_BASE_URI`) + - 飞书:`OAUTH2_FEISHU_CLIENT_ID` / `OAUTH2_FEISHU_CLIENT_SECRET` + (国际版 Lark 再设 `OAUTH2_FEISHU_AUTHORIZE_URI` / `OAUTH2_FEISHU_BASE_URI`) + + 留空即不展示该入口,无需改配置文件。注意:飞书邮箱由企业管理员导入、未经用户 + 确认,因此 `emailVerified` 恒为 false;若在 `application.yml` 中把 + `skillhub.access-policy.mode` 设为 `EMAIL_DOMAIN`,该策略会拒绝所有未验证邮箱, + 飞书登录将一律失败。启用飞书时请保留默认的 `OPEN` 或改用其他准入模式。 - 如果要启用密码重置验证码邮件,参见:`docs/19-smtp-password-reset-email-setup.md` ## 8 OIDC 登录配置 diff --git a/docs/skillhub/en/faq.md b/docs/skillhub/en/faq.md index acfe6d89..c00abdf8 100644 --- a/docs/skillhub/en/faq.md +++ b/docs/skillhub/en/faq.md @@ -190,9 +190,14 @@ A: Skill names are generally in English; Chinese names are not currently support A: As long as you have permission to view it, it can generally be downloaded. -## Q: How do I hide or remove the GitHub / GitLab SSO login options on the login page? +## Q: How do I hide or remove third-party SSO login options on the login page? -A: Edit `application.yml` and comment out or delete the `github` and `gitlab` blocks under `spring.security.oauth2.client.registration`, along with their corresponding `provider` sections. Spring Boot then won't create these registrations at startup, and the login page won't show those entries. +A: Login entries are config-driven: `/api/v1/auth/methods` only returns registrations that have a real client id. When a client id is empty or contains `placeholder`, that entry never reaches the login page. + +So there are two ways to hide one: + +- Leave the matching environment variable unset (for example, omit `OAUTH2_FEISHU_CLIENT_ID`). No config file change needed. +- Or edit `application.yml` and comment out or delete the relevant registration block (`github`, `gitlab`, `feishu`) under `spring.security.oauth2.client.registration`, along with its `provider` section. Spring Boot then won't create that registration at startup. ## Q: Is SkillHub's security scanning (Skill Scanner) developed in-house by iFLYTEK? What license does it use? diff --git a/docs/skillhub/faq.md b/docs/skillhub/faq.md index 8906150c..75054ca0 100644 --- a/docs/skillhub/faq.md +++ b/docs/skillhub/faq.md @@ -190,9 +190,17 @@ A: skill name 一般使用英文,目前不支持中文名(在 OpenClaw 中 A: 只要拥有可查看的权限,一般都可以下载。 -## Q: 如何隐藏或删除登录页的 GitHub / GitLab SSO 登录方式? +## Q: 如何隐藏或删除登录页的第三方 SSO 登录方式? -A: 修改 `application.yml`,注释或删除 `spring.security.oauth2.client.registration` 下的 `github` 和 `gitlab` 两块,并删除对应的 `provider` 段。Spring Boot 启动时便不会创建这两个注册,登录页也不会再显示对应入口。 +A: 登录入口是配置驱动的:`/api/v1/auth/methods` 只返回配置了真实 client id 的 +注册,client id 为空或包含 `placeholder` 时该入口不会出现在登录页。 + +所以隐藏某个入口有两种方式: + +- 留空对应的环境变量即可(例如不设置 `OAUTH2_FEISHU_CLIENT_ID`),无需改动配置文件。 +- 或修改 `application.yml`,注释/删除 `spring.security.oauth2.client.registration` + 下对应的注册块(`github`、`gitlab`、`feishu`)以及对应的 `provider` 段, + Spring Boot 启动时便不会创建该注册。 ## Q: SkillHub 的安全扫描(Skill Scanner)是讯飞自研的吗?使用什么协议? diff --git a/web/public/feishu-logo.svg b/web/public/feishu-logo.svg index 0cb86de7..f929a53d 100644 --- a/web/public/feishu-logo.svg +++ b/web/public/feishu-logo.svg @@ -1,2 +1,2 @@ - \ No newline at end of file + \ No newline at end of file