声明
本文由 🤖AI 协作完成, 内容已过实际测试.
前言:为什么我们需要一个“不安全”的 Keycloak?
在做企业级软件的私有化交付、内网 POC(概念验证)或本地开发时,我们经常面临一个尴尬的处境:环境受限。
- 没有域名:只有裸 IP(如
192.168.x.x)。 - 没有 SSL 证书:无法配置 HTTPS。
- 网络隔离:服务跑在 Docker 容器里,宿主机防火墙策略严格。
Keycloak 作为业界最强大的开源 IAM(身份访问管理)系统,默认的安全策略非常严格(强制 HTTPS、强制 Localhost 访问),这导致在上述“不完美”的内网环境中部署时,经常遇到管理控制台进不去、OIDC 登录无限重定向、Issuer 校验失败等“神坑”。
本文将总结一套经过实战验证的最佳实践,教你如何通过 Docker 快速搭建一个开箱即用、支持 HTTP、配置固化的 Keycloak 服务。
1. 核心架构:容器化配置的“三大纪律”
为了让 Keycloak 在纯 HTTP 和 Docker 网络中正常工作,我们需要打破它的默认规则。以下是一个用于 POC 的 docker-compose.yml 配置范本:
1 | services: |
关键配置解读:
- **
KC_HOSTNAME**:这是最关键的一行。OIDC 协议要求 Token 中的iss(Issuer) 字段必须与客户端请求的地址一致。如果这里不写死为 IP,Keycloak 可能会签发localhost的 Token,导致你的服务报错Issuer Mismatch。 - **
start-dev**:对于 POC 或临时演示,使用 H2 内存/文件数据库足够,无需额外部署 PostgreSQL。 - **
extra_hosts**:在 Docker 容器内部,直接访问宿主机 IP 往往会被防火墙拦截。通过host-gateway映射,让容器流量走 Docker 网关,确保网络互通。
2. 初始化工作流:从“手动点击”到“自动化镜像”
在私有化交付中,我们不能指望现场实施人员去 Keycloak 控制台手动创建 Realm 和 Client。我们需要实现 Configuration as Code (配置即代码) 。
1. 准备阶段:手动配置与导出
首先,启动官方 Keycloak 镜像,在浏览器中手动完成以下配置:
- 创建一个新的 Realm(例如
dip)。 - 创建 Client(设置
Access Type: confidential)。 - 技巧:在
Valid Redirect URIs中配置*(通配符),因为私有化部署的 IP 是未知的,这样可以适配任何客户环境。 - 导出配置:进入
Realm Settings->Action->Partial Export,导出为dip-realm.json。
2. 构建阶段:自定义镜像
编写 Dockerfile,利用 Keycloak 的 --import-realm 机制,将配置固化到镜像中:
1 | FROM quay.io/keycloak/keycloak:26.5.4 |
这样,客户拿到的镜像启动后,就已经有了配置好的 Realm 和 Client,真正的开箱即用。
3. 常见问题修复:解决“HTTPS Required”死锁
这是内网部署最大的痛点:当你通过 http://192.168.x.x:8083 访问 Keycloak 管理控制台时,界面会报错 **”HTTPS Required”**,导致无法登录管理员账号。
这是因为 Keycloak 的 Master Realm 默认安全策略是 sslRequired=external(非 Localhost 必须 HTTPS)。
方法 A:热修复(适用于调试)
如果容器已经跑起来了,可以通过命令行工具 kcadm.sh 实时修改配置:
1 | # 1. 进入容器 |
刷新浏览器,你会发现控制台可以登录了。
方法 B:永久修复(推荐方案)
为了防止重启容器后配置丢失,或者为了交付给客户,我们需要使用 Partial Import(增量导入) 机制来永久覆盖这个设置。
创建一个精简版的
master-realm.json:1
2
3
4
5{
"realm": "master",
"enabled": true,
"sslRequired": "none"
}注意:不要包含
users字段,以免覆盖管理员账号;不要包含id字段,以免冲突。更新
Dockerfile,将此文件也复制进去:1
COPY ./infra/keycloak/realm/master-realm.json /opt/keycloak/data/import/master-realm.json
Keycloak 启动时会检测到 master 域的导入文件,并自动将 SSL 策略更新为 none。
4. 客户端集成的小贴士
在解决了 Keycloak 端的问题后,你的应用(Client)可能会遇到 “登录后无限重定向” 的问题。
原因:现代浏览器对 Cookie 的安全限制。
如果你的应用在设置 Session Cookie 时标记了 Secure(仅限 HTTPS),但你在内网使用的是 HTTP,浏览器会拒绝保存 Cookie。
结果就是:Keycloak 认证成功 -> 跳回应用 -> 应用发现没 Cookie (未登录) -> 跳回 Keycloak -> Keycloak 发现已登录 -> 跳回应用 -> 死循环。
解决方案:
在你的代码中判断 FRONTEND_URL:
- 如果是
https://开头:设置Secure=True,SameSite=Lax。 - 如果是
http://开头:强制设置Secure=False,SameSite=Lax。
5. 总结
要在私有化、纯 HTTP 的 Docker 环境中驯服 Keycloak,核心在于:
- 网络层:使用
KC_HOSTNAME绑定 IP,使用extra_hosts打通容器内外。 - 配置层:使用
import机制固化 Realm 配置,实现自动化交付。 - 安全层:通过导入精简版
master-realm.json彻底解除 HTTPS 限制。
掌握了这一套打法,无论是 POC 演示还是内网交付,你都能在 5 分钟内拉起一套标准的 OIDC 认证中心。