认证与多租户
认证与多租户
相关源文件
本章引用的主要源码文件:
backend/alembic/versions/74379b447d4c_add_paste_as_tile_to_user.pybackend/onyx/auth/email_utils.pybackend/onyx/auth/schemas.pybackend/onyx/auth/users.pybackend/onyx/db/enums.pybackend/onyx/db/models.pybackend/onyx/db/user_preferences.pybackend/onyx/server/manage/get_state.pybackend/onyx/server/manage/models.pybackend/onyx/server/manage/users.pybackend/tests/api/test_api.pybackend/tests/unit/onyx/auth/test_single_tenant_jwt_strategy.pydeployment/aws_ecs_fargate/cloudformation/services/onyx_nginx_service_template.yamldeployment/aws_ecs_fargate/cloudformation/services/onyx_web_server_service_template.yamlweb/src/app/auth/join/page.tsxweb/src/app/auth/login/EmailPasswordForm.tsxweb/src/app/auth/login/LoginPage.tsxweb/src/app/auth/login/SignInButton.tsxweb/src/app/auth/login/page.tsxweb/src/app/auth/signup/page.tsxweb/src/app/auth/verify-email/Verify.tsxweb/src/app/auth/waiting-on-verification/page.tsxweb/src/app/layout.tsxweb/src/app/page.tsxweb/src/components/OnyxInitializingLoader.tsxweb/src/components/auth/AuthFlowContainer.tsxweb/src/components/settings/lib.tsweb/src/hooks/useCurrentUser.tsweb/src/hooks/useTokenRefresh.test.tsxweb/src/hooks/useTokenRefresh.tsweb/src/lib/constants.tsweb/src/lib/user.tsweb/src/lib/userSS.tsweb/src/providers/UserProvider.tsxweb/tests/e2e/auth/email_verification.spec.ts
本文档介绍了 Onyx 的认证系统与多租户架构,涵盖支持的认证方法(基础认证、OAuth、OIDC、SAML)、会话管理策略、用户角色以及基于模式的完全数据隔离的多租户实现。
关于具体实现的详细信息,请参见以下子页面:
- 认证方法 —— OAuth、OIDC、SAML 及邮箱验证的详细配置。
- 多租户架构 —— 模式隔离与租户预置的技术深度解析。
- 用户角色与权限 ——
UserRole枚举及角色层级参考。 - 会话管理 —— Redis、Postgres 和 JWT 会话后端的对比。
概述
Onyx 的认证系统基于 fastapi-users 构建,并针对多租户场景进行了自定义扩展。该系统支持多种部署模式与认证方法:
| 特性 | 单租户 | 多租户 |
|---|---|---|
| 认证类型 | disabled、basic、google_oauth、oidc、saml | cloud(Google OAuth) |
| 数据隔离 | 共享 public 模式 | 按租户隔离的 PostgreSQL 模式(tenant_<uuid>) |
| 会话后端 | redis、postgres 或 jwt | redis(配合 TenantRedis 包装器) |
| 用户管理 | UserManager + SQLAlchemyUserDatabase | UserManager + SQLAlchemyUserAdminDB |
| 上下文追踪 | 不适用 | CURRENT_TENANT_ID_CONTEXTVAR |
核心组件:
UserManager(backend/onyx/auth/users.py:39-44):处理用户创建、认证和 OAuth 回调。AuthenticationBackend(backend/onyx/auth/users.py:45):将CookieTransport与所选策略结合。CURRENT_TENANT_ID_CONTEXTVAR(shared_configs/contextvars.py:155-156):用于在多租户模式下追踪当前活跃租户的上下文变量。AuthType(backend/onyx/configs/constants.py:107):定义支持的认证模式的枚举。
来源: backend/onyx/auth/users.py:39-51、backend/onyx/configs/app_configs.py:86-102、shared_configs/contextvars.py:155-156、backend/onyx/configs/constants.py:107
认证系统架构
认证流程示意图
下图展示了从高层认证请求到底层代码实体的完整流程。
请求认证流程:
来源: backend/onyx/auth/users.py:45-53、backend/onyx/auth/users.py:86-101、backend/onyx/db/models.py:126-129
认证类型
支持的认证方法
Onyx 通过 AUTH_TYPE 环境变量确定认证类型,该变量映射到 AuthType 枚举:
| AuthType | 描述 | 使用场景 |
|---|---|---|
| DISABLED | 无需认证 | 仅限开发/测试环境 |
| BASIC | 邮箱/密码认证(可选邮箱验证) | 标准自托管部署 |
| GOOGLE_OAUTH | Google OAuth 2.0 | 单租户与 Google Workspace 集成 |
| OIDC | OpenID Connect | 企业 SSO 集成 |
| SAML | SAML 2.0 | 企业 SSO 集成 |
| CLOUD | 多租户 Google OAuth | Onyx Cloud(多租户 SaaS) |
前端集成: Web 应用在 web/src/lib/constants.ts(web/src/lib/constants.ts:3-9)中镜像了这些类型,并使用 getAuthTypeMetadataSS(web/src/lib/userSS.ts:17-63)获取服务端配置以渲染登录界面。
来源: backend/onyx/configs/app_configs.py:88、backend/onyx/configs/constants.py:107、web/src/lib/constants.ts:3-9、web/src/lib/userSS.ts:17-63
密码认证
密码要求
密码校验由 UserManager 执行,使用 app_configs.py 中定义的可配置约束:
| 配置项 | 默认值 | 环境变量 |
|---|---|---|
| 最小长度 | 8 | PASSWORD_MIN_LENGTH |
| 最大长度 | 128 | PASSWORD_MAX_LENGTH |
| 要求大写字母 | false | PASSWORD_REQUIRE_UPPERCASE |
| 要求小写字母 | false | PASSWORD_REQUIRE_LOWERCASE |
| 要求数字 | false | PASSWORD_REQUIRE_DIGIT |
| 要求特殊字符 | false | PASSWORD_REQUIRE_SPECIAL_CHAR |
特殊字符: !"#$%&'()*+,-./:;<=>?@[\]^_{|}~(定义在 PASSWORD_SPECIAL_CHARS 中,位于 backend/onyx/configs/constants.py:113)。
来源: backend/onyx/configs/app_configs.py:91-96、backend/onyx/configs/constants.py:113
邮箱验证与限制
邮箱验证由 REQUIRE_EMAIL_VERIFICATION 标志控制(backend/onyx/configs/app_configs.py:98)。
关键特性:
- 域名限制:
VALID_EMAIL_DOMAINS(backend/onyx/configs/app_configs.py:102)将注册限制在特定的企业域名内。 - 临时邮箱检测:
is_disposable_email(backend/onyx/auth/disposable_email_validator.py)阻止使用临时邮箱服务注册。 - 验证流程:
send_user_verification_email(backend/onyx/auth/users.py:77)触发验证过程,通过 SMTP 发送包含令牌的链接。
关于 SMTP 和域名过滤器的设置详情,请参见认证方法。
来源: backend/onyx/configs/app_configs.py:98-102、backend/onyx/auth/users.py:77、backend/onyx/auth/disposable_email_validator.py
多租户架构
基于模式的数据隔离
在多租户模式(MULTI_TENANT=True)下,Onyx 使用 PostgreSQL 模式进行数据隔离。每个租户拥有自己的模式,而共享元数据则存储在 POSTGRES_DEFAULT_SCHEMA(通常为 public)中。
租户预置: 系统使用 get_or_provision_tenant 逻辑处理租户的生命周期,通常通过 AvailableTenant 记录预先预置模式。
多租户代码实体:
CURRENT_TENANT_ID_CONTEXTVAR(shared_configs/contextvars.py:155):在请求生命周期内保存当前租户 ID。get_session_with_current_tenant(backend/onyx/db/engine/sql_engine.py:123):返回一个限定于当前活跃租户模式的数据库会话。AccountType(backend/onyx/db/enums.py:7-20):区分STANDARD、BOT和ANONYMOUS账户的枚举。
关于模式迁移和租户预置的详细信息,请参见多租户架构。
来源: shared_configs/configs.py:153、shared_configs/contextvars.py:155、backend/onyx/db/engine/sql_engine.py:123-124、backend/onyx/db/enums.py:7-20
用户角色与权限
用户角色层级
Onyx 使用 UserRole 枚举(backend/onyx/auth/schemas.py:13)实现了基于角色的访问控制系统。
| 角色 | 描述 |
|---|---|
ADMIN | 完全的系统管理访问权限。 |
GLOBAL_CURATOR | 对所有组的管理操作权限。 |
CURATOR | 对特定分配组的管理操作权限。 |
BASIC | 拥有聊天和搜索访问权限的标准用户。 |
LIMITED | 仅能访问一组受限的基础 API 端点。 |
SLACK_USER | 通过 Slack 交互的用户。 |
EXT_PERM_USER | 来自外部权限同步的用户。 |
账户类型逻辑: AccountType.is_web_login() 方法(backend/onyx/db/enums.py:22-27)判断某个账户类型是否支持交互式 Web 登录(例如,BOT 和 EXT_PERM_USER 无法通过 Web 界面登录)。
关于每个角色的权限能力详情,请参见用户角色与权限。
来源: backend/onyx/auth/schemas.py:13、backend/onyx/db/enums.py:7-27、backend/onyx/db/models.py:129
会话管理
会话后端选项
Onyx 支持多种会话存储后端,定义在 AuthBackend(backend/onyx/auth/schemas.py:82)中:
| 后端 | 策略类 | 存储位置 |
|---|---|---|
redis | RedisStrategy | Redis(按租户 ID 添加前缀) |
postgres | DatabaseStrategy | 数据库中的 access_token 表 |
jwt | JWTStrategy | 客户端签名的 Cookie |
配置: AUTH_BACKEND(backend/onyx/configs/app_configs.py:86)和 SESSION_EXPIRE_TIME_SECONDS(backend/onyx/configs/app_configs.py:99)控制会话的持久化和过期时间。
关于会话创建和令牌过期的详细信息,请参见会话管理。
来源: backend/onyx/auth/schemas.py:82、backend/onyx/configs/app_configs.py:86-99、backend/onyx/db/models.py:126