OAuth 集成(中文译文)
原始 DeepWiki 页面:https://deepwiki.com/open-webui/open-webui/11.2-oauth-integration
翻译时间:2026-06-09T16:10:39.876Z
翻译模型:deepseek-chat
原文字符数:13337
项目:Open WebUI (open-webui)
---
OAuth 集成
相关源文件
以下文件为本 Wiki 页面的生成提供了上下文:
backend/open_webui/config.pybackend/open_webui/env.pybackend/open_webui/internal/db.pybackend/open_webui/main.pybackend/open_webui/migrations/env.pybackend/open_webui/models/oauth_sessions.pybackend/open_webui/retrieval/loaders/mistral.pybackend/open_webui/routers/auths.pybackend/open_webui/routers/configs.pybackend/open_webui/utils/auth.pybackend/open_webui/utils/oauth.pybackend/open_webui/utils/webhook.pysrc/lib/apis/configs/index.tssrc/lib/apis/tools/index.tssrc/lib/apis/users/index.tssrc/lib/components/chat/MessageInput/InputMenu.sveltesrc/lib/components/chat/MessageInput/IntegrationsMenu.sveltesrc/lib/utils/onedrive-file-picker.ts
本文档描述了 Open WebUI 中的 OAuth 2.1 认证系统,该系统允许用户使用外部身份提供者登录,并允许工具服务器通过 OAuth 保护的 API 进行认证。有关包括 JWT 和 LDAP 在内的通用认证方法,请参阅 认证方法。
---
概述
Open WebUI 实现了 OAuth 2.1,并遵循模型上下文协议(MCP)规范进行动态客户端注册。该系统同时支持多个 OAuth 提供者、自动令牌刷新,以及与需要 OAuth 认证的外部工具服务器的集成。
主要特性:
- 动态客户端注册:对于符合 MCP 的服务器,无需手动配置提供者
backend/open_webui/utils/oauth.py:340-457。 - 自动令牌刷新:访问令牌的加密存储和后台刷新
backend/open_webui/utils/oauth.py:660-730。 - 用户预置:自动创建账户,并同步角色和组
backend/open_webui/utils/oauth.py:850-1000。 - 多提供者支持:管理多个并发 OAuth 身份的会话
backend/open_webui/models/oauth_sessions.py:25-43。 - 加密:使用 Fernet 对称加密保护敏感的客户端和会话数据
backend/open_webui/utils/oauth.py:178-206。
来源: backend/open_webui/utils/oauth.py:1-1150, backend/open_webui/env.py:542-565, backend/open_webui/models/oauth_sessions.py:1-50
---
系统架构
组件概览
下图将高级系统组件映射到 OAuth 实现中的具体代码实体。
graph TB
subgraph "客户端浏览器"
UI["前端 UI"]
end
subgraph "FastAPI 应用"
AuthRouter["routers/auths.py<br/>OAuth 路由"]
OAuthManager["OAuthClientManager<br/>utils/oauth.py"]
ConfigRouter["routers/configs.py<br/>注册端点"]
end
subgraph "数据与存储空间"
OAuthSessions["OAuthSessions 模型<br/>models/oauth_sessions.py"]
Users["Users 模型<br/>models/users.py"]
Groups["Groups 模型<br/>models/groups.py"]
AppConfig["PersistentConfig<br/>config.py"]
end
subgraph "安全层"
Fernet["Fernet 密码<br/>cryptography.fernet"]
EncKeys["OAUTH_CLIENT_INFO_ENCRYPTION_KEY<br/>OAUTH_SESSION_TOKEN_ENCRYPTION_KEY"]
end
subgraph "外部服务"
Provider["OAuth 提供者<br/>授权服务器"]
ToolServer["工具服务器<br/>OAuth 保护的 API"]
end
UI -->|"发起登录"| AuthRouter
AuthRouter -->|"get_client()"| OAuthManager
OAuthManager -->|"读取 TOOL_SERVER_CONNECTIONS"| AppConfig
AuthRouter -->|"重定向"| Provider
Provider -->|"回调"| AuthRouter
AuthRouter -->|"OAuthSessions.insert_new_session()"| OAuthSessions
AuthRouter -->|"Users.update_user_by_id()"| Users
AuthRouter -->|"Groups.sync_groups_by_group_names()"| Groups
ConfigRouter -->|"register_oauth_client()"| OAuthManager
OAuthManager -->|"encrypt_data()"| Fernet
Fernet -->|"存储 Blob"| AppConfig
OAuthManager -->|"_refresh_token()"| Provider
来源: backend/open_webui/utils/oauth.py:459-567, backend/open_webui/routers/auths.py:98-151, backend/open_webui/models/oauth_sessions.py:70-145, backend/open_webui/config.py:214-231
---
动态客户端注册
动态客户端注册允许 Open WebUI 通过发现提供者的元数据端点,自动注册为 OAuth 客户端。这主要用于 MCP(模型上下文协议)工具服务器。
注册流程
此图详细描述了从配置 API 到加密存储的完整流程。
sequenceDiagram
participant Admin
participant ConfigRouter as "routers/configs.py"
participant RegFunc as "get_oauth_client_info_with_dynamic_client_registration()"
participant Discovery as "发现逻辑"
participant AuthServer as "OAuth 授权服务器"
participant Encryption as "encrypt_data()"
participant Storage as "PersistentConfig (TOOL_SERVER_CONNECTIONS)"
Admin->>ConfigRouter: POST /oauth/clients/register
ConfigRouter->>RegFunc: 使用 server_url 调用
RegFunc->>Discovery: 生成发现 URL
Note over Discovery: /.well-known/oauth-authorization-server<br/>/.well-known/openid-configuration
RegFunc->>AuthServer: GET 发现端点
AuthServer-->>RegFunc: OAuthMetadata (JSON)
RegFunc->>AuthServer: POST /register (OAuthClientMetadata)
AuthServer-->>RegFunc: OAuthClientInformationFull
RegFunc->>Encryption: encrypt_data(client_info)
Encryption-->>RegFunc: 加密字符串
RegFunc-->>ConfigRouter: 返回客户端信息
ConfigRouter->>Storage: 通过 async_save_config() 持久化到数据库
来源: backend/open_webui/utils/oauth.py:340-457, backend/open_webui/utils/oauth.py:193-202, backend/open_webui/routers/configs.py:107-141, backend/open_webui/config.py:192-206
发现机制
系统会尝试多种发现 URL 模式来查找 OAuth 元数据:
- MCP 资源发现:从
WWW-Authenticate头中提取authorization_serversbackend/open_webui/utils/oauth.py:249-270。 - 基于路径的发现:检查服务器路径下的
/.well-known/oauth-authorization-server和/.well-known/openid-configurationbackend/open_webui/utils/oauth.py:275-300。 - 基于根 URL 的发现:检查域根目录下的发现端点
backend/open_webui/utils/oauth.py:305-330。
来源: backend/open_webui/utils/oauth.py:249-330
---
OAuth 客户端管理器
OAuthClientManager 类(定义于 backend/open_webui/utils/oauth.py)是 OAuth 操作的核心协调器,负责管理 authlib 客户端的生命周期。
关键方法
| 方法 | 作用 | 实现细节 |
|---|---|---|
add_client | 向 Authlib 注册客户端 | 使用 OAuthClientInformationFull 初始化 authlib.integrations.starlette_client.OAuth backend/open_webui/utils/oauth.py:465-507。 |
ensure_client_from_config | 延迟加载 | 按需从 TOOL_SERVER_CONNECTIONS 配置中解密并注册客户端 backend/open_webui/utils/oauth.py:509-551。 |
get_oauth_token | 令牌检索 | 从 OAuthSessions 获取令牌,若距离过期不足 5 分钟则触发刷新 backend/open_webui/utils/oauth.py:660-701。 |
_refresh_token | 令牌刷新 | 使用 refresh_token 调用提供者的令牌端点,并更新 OAuthSessions backend/open_webui/utils/oauth.py:703-730。 |
来源: backend/open_webui/utils/oauth.py:459-730
---
令牌管理与刷新
OAuth 会话存储
令牌存储在 oauth_session 表中,由 OAuthSessions 模型管理 backend/open_webui/models/oauth_sessions.py:1-20。
数据安全:
- 加密:所有令牌(访问令牌、刷新令牌和 ID 令牌)在写入数据库之前均使用
FERNET进行加密backend/open_webui/models/oauth_sessions.py:89-97。 - 密钥来源:加密密钥源自
OAUTH_SESSION_TOKEN_ENCRYPTION_KEY。如果提供的密钥长度不是 44 个字符,则会使用 SHA256 进行哈希并 base64 编码,以满足 Fernet 的要求backend/open_webui/models/oauth_sessions.py:72-81。
来源: backend/open_webui/models/oauth_sessions.py:70-145, backend/open_webui/utils/oauth.py:180-190
令牌刷新逻辑
flowchart TD
Start["get_oauth_token(user_id, client_id)"]
GetSession["OAuthSessions.get_session_by_provider_and_user_id()"]
CheckExpiry{"expires_at - now < 300s?"}
RefreshToken["_refresh_token(session)"]
UpdateSession["OAuthSessions.update_session_by_id()"]
ReturnToken["返回令牌字典"]
Start --> GetSession
GetSession --> CheckExpiry
CheckExpiry -- "是" --> RefreshToken
CheckExpiry -- "否" --> ReturnToken
RefreshToken -- "成功" --> UpdateSession
UpdateSession --> ReturnToken
RefreshToken -- "失败" --> Delete["OAuthSessions.delete_session_by_id()"]
来源: backend/open_webui/utils/oauth.py:660-730, backend/open_webui/models/oauth_sessions.py:108-145
---
用户认证流程
当用户通过 OAuth 进行认证时,Open WebUI 会根据身份提供者(IdP)提供的声明同步其个人资料、角色和组。
声明映射
系统使用可配置的声明来提取用户信息:
| 信息 | 声明变量 | 默认值 |
|---|---|---|
| 邮箱 | OAUTH_EMAIL_CLAIM | email |
| 名称 | OAUTH_USERNAME_CLAIM | name |
| 头像 | OAUTH_PICTURE_CLAIM | picture |
| 角色 | OAUTH_ROLES_CLAIM | roles |
| 组 | OAUTH_GROUPS_CLAIM | groups |
来源: backend/open_webui/utils/oauth.py:50-55, backend/open_webui/utils/oauth.py:126-131
角色与组同步
- 角色管理:如果
ENABLE_OAUTH_ROLE_MANAGEMENT为 true,系统会检查用户的声明中是否包含OAUTH_ADMIN_ROLES或OAUTH_ALLOWED_ROLES中定义的角色backend/open_webui/utils/oauth.py:43-57。 - 组管理:如果
ENABLE_OAUTH_GROUP_MANAGEMENT为 true,系统会解析OAUTH_GROUPS_CLAIM(使用OAUTH_GROUPS_SEPARATOR分割),并通过Groups.sync_groups_by_group_names更新组成员关系backend/open_webui/utils/oauth.py:44-52。 - 组创建:如果启用了
ENABLE_OAUTH_GROUP_CREATION,在声明中发现的新组会自动在数据库中创建backend/open_webui/utils/oauth.py:45。
来源: backend/open_webui/utils/oauth.py:114-141, backend/open_webui/utils/oauth.py:199-241
---
安全特性
加密与存储
Open WebUI 使用两个不同的加密密钥来保障 OAuth 安全:
OAUTH_CLIENT_INFO_ENCRYPTION_KEY:用于加密存储在应用配置中的 OAuth 客户端密钥和元数据backend/open_webui/env.py:552-554。OAUTH_SESSION_TOKEN_ENCRYPTION_KEY:由OAuthSessions用于加密用户特定的访问令牌和刷新令牌backend/open_webui/models/oauth_sessions.py:72-74。
两者均使用 cryptography.fernet.Fernet 实现 backend/open_webui/utils/oauth.py:178-190, backend/open_webui/models/oauth_sessions.py:83-88。
来源: backend/open_webui/env.py:552-554, backend/open_webui/models/oauth_sessions.py:72-74, backend/open_webui/utils/oauth.py:178-190, backend/open_webui/models/oauth_sessions.py:83-88
Cookie 管理
在 OAuth 回调或会话创建期间,系统会设置多个 Cookie 以维持会话:
token:主要的 Open WebUI JWT,设置了httponly、samesite和secure标志backend/open_webui/routers/auths.py:128-135。oauth_id_token:如果ENABLE_OAUTH_ID_TOKEN_COOKIE为 true,原始的 OIDC ID 令牌会存储在 Cookie 中backend/open_webui/env.py:548-550。
来源: backend/open_webui/routers/auths.py:124-136, backend/open_webui/env.py:516-533
---
错误处理
通过 _build_oauth_callback_error_message 提供标准化的错误消息,该函数处理多种异常类型:
- OAuth2Error:从 IdP 响应中提取错误和描述
backend/open_webui/utils/oauth.py:1020-1025。 - HTTPException:使用 FastAPI 的 detail 字段
backend/open_webui/utils/oauth.py:1026-1027。 - ClientResponseError:捕获上游状态码和消息
backend/open_webui/utils/oauth.py:1028-1029。
来源: backend/open_webui/utils/oauth.py:1015-1040