OpenWebUi-安全与认证配置
OpenWebUi-安全与认证配置
Prorise3.9. 安全与认证配置
这一章讲的是“谁能登录、谁能调用 API、用户身份如何同步、会话如何保活”。
如果你是个人用户,这部分很多配置可以先不动;但只要进入团队协作、公司内网、对接脚本或自动化系统,这一章就会变成必修课。
在开始之前,先解释几个经常会混在一起的术语:
- 认证(Authentication):证明“你是谁”。例如账号密码登录、LDAP 登录、Google 登录。
- 授权(Authorization):决定“你能做什么”。例如能不能看某个模型、能不能导出模型、能不能管理工具。
- API Key:发给程序用的密钥,适合脚本、集成平台、外部服务调用 Open WebUI API。
- LDAP:企业常见的目录服务协议,很多公司的 AD(Active Directory)也兼容这套方式。
- OAuth / OIDC:第三方登录体系。OAuth 偏“授权”,OIDC 是建立在 OAuth 之上的“身份登录”标准。
- SCIM:自动开通和回收账号的标准,不负责“登录”,而负责“账号生命周期同步”。
API 密钥认证
这是什么
Open WebUI 支持为用户生成 API Key,让外部脚本、自动化流程、内部平台、工作流引擎通过 HTTP API 访问它。
典型场景包括:
- 用 Python、Node.js 或 Shell 脚本调用聊天接口
- 用企业内部系统转发请求到 Open WebUI
- 给工作流平台、Bot、自动化任务提供一个稳定认证方式
它和“浏览器登录 Cookie”不是一回事:
- 浏览器登录主要给人用
- API Key 主要给程序用
如何启用
管理员面板 → 设置 → 通用 → 启用 API Key
启用后,用户就可以在自己的账号设置中创建 API Key。
当前版本除了总开关外,还支持 API Key Endpoint Restrictions,也就是“限制 API Key 只能访问哪些接口”。这个能力很重要,因为它可以避免把一把过大的密钥发给外部系统。
用户如何生成密钥
点击头像 → 设置 → 账号 → API 密钥 → 点击“创建新密钥”
创建后要立即保存,因为这类密钥通常不会反复明文展示。
调用示例
1 | curl -X POST http://localhost:3000/api/chat \ |
官方建议理解
官网当前的方向不是“默认把所有接口都敞开”,而是:
- 可以启用 API Key
- 可以进一步启用接口级限制
- 在可信内网环境里可以更宽松,在生产环境则建议更严格
我的管理方式
在我的环境里,API Key 主要给“程序”而不是“人”使用,所以我通常这样管理:
- 浏览器用户走正常登录,不给所有人默认要求 API Key。
- 只有确实需要脚本调用的账号,才生成 API Key。
- 给外部系统时,优先启用接口限制,不给过大的权限面。
- 定期清理不再使用的密钥,避免历史脚本长期持有可用凭证。
- 如果只是临时测试,我会单独创建测试用密钥,不和正式环境长期复用。
LDAP 集成
这是什么
LDAP 可以理解为“公司统一通讯录 / 账号目录”的标准接口。
如果你所在的组织已经有 AD、OpenLDAP 或其他企业目录系统,那么 Open WebUI 可以直接对接这个目录,让员工使用公司账号登录,而不是在 Open WebUI 里重复创建本地账号。
适合谁
- 公司内网部署
- 已有统一身份管理
- 希望账号、邮箱、用户名来自企业目录
个人部署、小团队、临时测试环境,通常不需要上 LDAP。
官方配置思路
LDAP 推荐先通过环境变量初始化,然后在管理员面板里继续维护。官网特别强调一件事:
如果启用了持久化配置(默认就是),很多环境变量只在第一次启动时读入;后续修改通常要在管理后台里改,而不是只改
docker-compose。
这点非常重要,也是很多人“明明改了环境变量,怎么界面没变”的根源。
当前版本常见环境变量
1 | environment: |
你会发现,这一版和很多旧博客里写的 LDAP_SERVER_URL、LDAP_BIND_DN 之类名字不完全一样。写文档时一定要以当前版本为准。
参数解释
| 参数 | 说明 |
|---|---|
ENABLE_LDAP | 是否启用 LDAP 登录 |
LDAP_SERVER_LABEL | 在界面里显示的 LDAP 名称 |
LDAP_SERVER_HOST / LDAP_SERVER_PORT | LDAP 服务器地址和端口 |
LDAP_ATTRIBUTE_FOR_MAIL | 从 LDAP 条目里取邮箱的字段 |
LDAP_ATTRIBUTE_FOR_USERNAME | 从 LDAP 条目里取用户名的字段 |
LDAP_APP_DN / LDAP_APP_PASSWORD | 用于查询目录的服务账号 |
LDAP_SEARCH_BASE | 搜索用户的根 DN |
LDAP_SEARCH_FILTER | 登录时查找用户的过滤器 |
LDAP_USE_TLS | 是否启用 TLS / StartTLS |
正确的排错顺序
不要一上来就怀疑 Open WebUI。
官网推荐的思路是:
- 先验证 LDAP 服务器本身通不通
- 再验证用户条目能不能查到
- 最后才看 Open WebUI 配置
例如:
1 | ldapsearch -x -H ldap://ldap.example.com:389 \ |
如果这一步都查不到用户,就不要继续在 WebUI 里盲改了。
我的管理方式
我自己的判断规则很简单:
- 如果是企业内部正式使用,并且员工已经有统一账号体系,我会优先接 LDAP。
- 如果只是个人站点、朋友共用、测试环境,我不会为了“看起来企业化”硬上 LDAP。
- 上 LDAP 后,我会尽量让用户名、邮箱、显示名都来自目录系统,避免 Open WebUI 自己成为第二套主数据来源。
OAuth / OIDC / SSO 集成
这是什么
这一组就是“第三方登录”。
最常见的使用方式是:
- 用 Google 账号登录
- 用 Microsoft / Entra ID 账号登录
- 用 GitHub 账号登录
- 用企业自己的 OIDC 服务登录
如果说 LDAP 更像“公司内网目录登录”,那 OAuth / OIDC 更像“现代网站统一登录”。
先说结论:本地开发完全可以配
而且你现在这个仓库已经改成了:
docker-compose.local.yaml自动读取.env.local- 本地端口由
OPEN_WEBUI_PORT控制 - Google、Microsoft、GitHub 三家都可以直接写在
.env.local
所以对读者来说,最容易跟做的方式就是:
- 去各自官网创建 OAuth 应用
- 把回调地址填成 Open WebUI 本地回调
- 把拿到的密钥填进
.env.local - 重启本地容器
本地统一配置模板
如果你的本地端口是 3000,那么 .env.local 先这样写:
1 | OPEN_WEBUI_PORT=3000 |
写完后执行:
1 | docker compose -f docker-compose.local.yaml up -d --build |
如果你的端口不是 3000,例如 5050,那上面所有 localhost:3000 都要统一改成 localhost:5050。
适用场景
如果你想直接使用 Google 账号登录,这是最常见的一种配置。
第 1 步:去 Google 官方后台创建应用
访问:
https://console.cloud.google.com/apis/credentials
进入后:
- 创建或选择一个 Project
- 打开
APIs & Services - 进入
Credentials(凭证) - 点击
Create Credentials - 选择
OAuth client ID - Application type 选择
Web application
第 2 步:登记回调地址
在 Authorized redirect URIs 中填写:
1 | http://localhost:3000/oauth/google/login/callback |
第 3 步:把拿到的密钥填入 .env.local
1 | GOOGLE_CLIENT_ID=你的 Google Client ID |
第 4 步:重启本地 Open WebUI
1 | docker compose -f docker-compose.local.yaml up -d --build |
注意事项
- Google 开发环境允许
http://localhost - 回调地址必须和后台里登记的 URI 完全一致
- 如果你改了端口,Google 后台也要一起改
适用场景
如果用户本身就在 Microsoft 365、Entra ID、企业账号体系里,这一项非常常见。
第 1 步:去 Microsoft Entra 后台注册应用
访问:
进入后:
- 打开
Microsoft Entra ID - 进入
App registrations - 点击
New registration - 创建一个应用
第 2 步:配置回调地址
在 Authentication 页面里添加:
1 | http://localhost:3000/oauth/microsoft/login/callback |
第 3 步:生成 Secret 并写入 .env.local
在 Certificates & secrets 中生成一个 Client secret,然后填入:
1 | MICROSOFT_CLIENT_ID=你的 Microsoft Client ID |
如果你只允许某一个租户登录,把 common 改成你的实际 Tenant ID 即可。
第 4 步:重启本地 Open WebUI
1 | docker compose -f docker-compose.local.yaml up -d --build |
注意事项
- Microsoft 也支持本地
localhost回调 - 本地开发可以先用
common - 正式环境建议单独使用正式域名和正式应用注册
适用场景
如果你的用户本身大量使用 GitHub,这是最容易理解、也最容易测试的一项。
第 1 步:去 GitHub Developer Settings 创建 OAuth App
访问:
https://github.com/settings/developers
进入后:
- 打开
OAuth Apps - 点击
New OAuth App
第 2 步:填写回调地址
最关键的是 Authorization callback URL:
1 | http://localhost:3000/oauth/github/login/callback |
第 3 步:把密钥填入 .env.local
1 | GITHUB_CLIENT_ID=你的 GitHub Client ID |
第 4 步:重启本地 Open WebUI
1 | docker compose -f docker-compose.local.yaml up -d --build |
注意事项
- GitHub 对 callback URL 也是精确匹配
- 如果后台填的是
127.0.0.1,本地配置也要统一成127.0.0.1 - 不要后台填
127.0.0.1,本地却写localhost
为了更容易排错,我建议不要一上来三个一起配,而是按这个顺序:
- 先配一个,例如 GitHub
- 测通之后,再加 Google
- 最后再加 Microsoft
这样如果出现问题,最容易定位。
最常见的报错就是:
redirect_uri_mismatch- 端口改了,但开放平台后台没改
.env.local改了,但容器没重启- 后台写的是
127.0.0.1,本地写的是localhost
SCIM 自动开通与回收
这是什么
SCIM 不是登录协议,而是“账号生命周期同步协议”。
它解决的问题是:
- 新员工入职时,自动在 Open WebUI 创建账号
- 员工信息变化时,自动同步更新
- 员工离职时,自动停用账号
- 用户组成员关系自动同步
所以可以把它理解成“自动开账号、改账号、停账号”的标准接口。
和 OAuth / LDAP 的关系
- LDAP / OAuth / OIDC:解决“怎么登录”
- SCIM:解决“账号怎么自动创建和同步”
很多企业会同时使用:
- 用 OIDC 登录
- 用 SCIM 做账号与组同步
当前版本配置
1 | environment: |
参数解释
| 参数 | 说明 |
|---|---|
SCIM_ENABLED | 是否启用 SCIM |
SCIM_TOKEN | 调用 SCIM API 的 Bearer Token |
SCIM_AUTH_PROVIDER | 用于把 SCIM externalId 和对应认证提供商关联起来,例如 microsoft、oidc |
这里的 SCIM_AUTH_PROVIDER 很容易被漏掉,但当前版本里它是重要配置,尤其是在账户关联和 externalId 保存上。
对接端点
SCIM Base URL:
1 | https://your-domain.com/api/v1/scim/v2/ |
常见资源端点:
| 资源 | 端点 |
|---|---|
| 用户 | /api/v1/scim/v2/Users |
| 组 | /api/v1/scim/v2/Groups |
我的管理方式
我把 SCIM 视为“企业级增强项”:
- 小规模自用:完全不需要
- 团队规模不大,但已有统一登录:先上 OAuth / LDAP,SCIM 可以以后再说
- 企业正式上生产:如果人事变动频繁、合规要求高,就值得上 SCIM
它的价值不在“让用户多一个登录按钮”,而在于减少人工维护账号、降低离职账号遗留风险。
会话、JWT 与 Cookie
这是什么
用户在浏览器里登录后,Open WebUI 需要一种机制记住登录状态,这通常会涉及:
- JWT:登录令牌
- Session Cookie:浏览器保存的登录凭证
- Secret Key:服务器用来签名和加密敏感数据的密钥
当前版本重点配置
1 | environment: |
参数解释
| 参数 | 说明 |
|---|---|
WEBUI_SECRET_KEY | 最关键的持久化密钥,用于会话签名和敏感数据解密 |
JWT_EXPIRES_IN | 登录令牌过期时间,例如 4w、7d |
WEBUI_SESSION_COOKIE_SAME_SITE | Cookie 的跨站策略 |
WEBUI_SESSION_COOKIE_SECURE | 是否只通过 HTTPS 发送 Cookie |
为什么 WEBUI_SECRET_KEY 非常重要
官网 FAQ 专门提到,如果你每次重建容器都不保留同一个 WEBUI_SECRET_KEY,会出现两类典型问题:
- 用户升级或重启后被全部强制退出
- 一些已经加密保存的令牌、API Key、OAuth 凭证无法解密
所以这个值一定要固定,不要让容器每次随机生成。
我的管理方式
这一点我会非常保守:
- 生产环境固定设置
WEBUI_SECRET_KEY - HTTPS 环境强制
WEBUI_SESSION_COOKIE_SECURE=true - 不把
JWT_EXPIRES_IN设成无限期 - 升级容器前先确认密钥仍然通过同样方式注入
这是最容易被忽略、但一出问题就会直接影响所有用户登录体验的一块。



