You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要
为
easytier-web添加 OIDC (OpenID Connect) 单点登录认证支持,允许用户通过外部身份提供商(如 Keycloak, Authentik, Okta, Azure AD)进行身份验证。核心变更
--allow-auto-create-user命令行标志,当easytier-core以未知用户名连接时,可自动为其拨备本地账号。create_user_and_join_users_group中,消除了原有register_new_user中的.unwrap()panic 风险。新增命令行选项
--oidc-issuer-url--oidc-client-id--oidc-client-secret/OIDC_CLIENT_SECRET环境变量--oidc-redirect-url--oidc-username-claimpreferred_username)--oidc-scopesopenid,profile)--oidc-disable-pkce--oidc-frontend-base-url--allow-auto-create-user新增 API 端点
/api/v1/auth/oidc/config/api/v1/auth/oidc/login/api/v1/auth/oidc/callbackOIDC 流程说明
安全措施
subtle库进行恒定时间比较(Constant-time comparison)验证 CSRF 状态,防止时序攻击。at_hash) 校验。SameSite=Lax以支持跨站认证重定向。已知局限
register_new_user和change_password在异步运行时中直接调用了 CPU 密集型的哈希函数(此为既有代码遗留问题,非本次 PR 引入)。SessionManagerLayer配置为SameSite::Lax,如果 API 与 Frontend 部署在完全不同的域名下(非同父域),OIDC 回调后浏览器不会携带 Cookie,导致用户始终处于未登录状态。当前假定通过反代将前后端置于同一域名下;若需完全跨域部署,后续需增加SameSite=None+Secure=true的可选配置。username_claim提取的用户名与本地username进行匹配,不区分用户来源(本地注册 vs OIDC)。这是有意为之的设计——同一用户名始终对应同一账户,无论通过密码还是 SSO 登录均操作同一身份。部署时管理员应确保 IdP 侧的用户名分配策略与本地用户体系一致。测试情况
自动化单元测试
dot_path_to_json_pointer覆盖各种边缘情况(嵌套路径、RFC 6901 转义、空段等)。集成 / 人工测试用例
一、CLI 参数验证
easytier-web,不传任何--oidc-*参数GET /api/v1/auth/oidc/config返回{"enabled": false}--oidc-issuer-url而不传--oidc-client-id和--oidc-redirect-url--oidc-issuer-url(如http://localhost:99999)--oidc-scopes,直接发起 OIDC 登录scope至少包含openid profile(按默认值)--no-web或不同的--web-server-port,但不传--oidc-frontend-base-urlOIDC_CLIENT_SECRET环境变量二、OIDC SSO 登录 — 正常流程
GET /api/v1/auth/oidc/config{"enabled": true};未启用时返回{"enabled": false}GET /api/v1/auth/oidc/logincode_challenge(PKCE)、state、nonce参数users组,回调后 302 重定向到前端,session cookie 有效,GET /api/v1/auth/check_login_status返回 200--oidc-frontend-base-url/--oidc-frontend-base-url http://localhost:3000http://localhost:3000--oidc-username-claim email启动email字段提取用户名--oidc-username-claim realm_access.roles.0启动--oidc-disable-pkce启动code_challenge参数,token 交换请求中不含 PKCE verifier--oidc-scopes profile,email,groups启动scope参数中包含openid(自动补充)、profile、email、groups三、OIDC SSO 登录 — 异常与安全
GET /api/v1/auth/oidc/login{"message": "OIDC is not enabled"}state参数替换为随机值{"message": "CSRF state mismatch"}code参数{"message": "Missing authorization code"}state参数{"message": "Missing state parameter in callback"}error=access_denied{"message": "PKCE was enabled but verifier is missing from session"}code参数进行回调{"message": "ID token verification failed"}{"message": "No ID token in response"}at_hash不匹配{"message": "Access token hash mismatch"}--oidc-username-claim指定一个 ID Token 中不存在的字段名{"message": "Could not extract username from token claims"}--oidc-username-claim指向非字符串字段(如对象/数组){"message": "Could not extract username from token claims"}cleanup_oidc_session清除)四、心跳自动创建用户
--allow-auto-create-user,用一个未注册的用户名作为 token 连接easytier-core--allow-auto-create-user,用一个未注册的用户名作为 token 连接users组,后续心跳正常处理--allow-auto-create-user,用一个已注册的用户名连接users组的默认权限,可正常使用五、用户注册回归
users组,可正常登录--disable-registration,尝试注册六、前端行为
{apiHost}/api/v1/auth/oidc/login,apiHost 已保存至 localStorageif (apiHost.value !== host) return)getOidcConfig静默返回{enabled: false})v-if="!isRegistering"限制)七、多 IdP 兼容性
--oidc-username-claim=nickname