Keycloak 统一身份认证实战:用 OIDC/SSO 把散落账号收拢成一个身份中心


自托管服务一多,"账号"就成了又一个麻烦:每开一个服务就要注册一套用户名密码,密码到处重复、忘了要重置、每个服务还要单独配权限。更别说想限制"只有家里人能访问""给朋友开个临时账号"。独立认证中心(IdP)就是把这摊子收拢的方案:用一个统一的身份服务管"我是谁、能不能进",其他应用只负责"认这个中心签发的凭证"。Keycloak 正是自托管里最常用的开源 IdP。这篇讲清 Keycloak 解决什么、OIDC/SSO 基础、怎么接反代与应用、怎么管用户与 MFA,以及常见坑与边界。

一、Keycloak 解决什么:把"每个应用一套账号"收拢成"一个身份中心"

分散账号的痛有三个:一是"重复注册"——每加一个自托管应用就要建一套账号;二是"密码地狱"——到处是密码、要么重复要么忘;三是"权限分散"——想给某人开访问、停某人的权限,要挨个应用改。Keycloak 作为身份与访问管理(IAM)中心,把"认证(你是谁)"集中:所有接入的应用都让用户先到 Keycloak 登录,Keycloak 签发会话/令牌给应用,应用据此放行。于是你只在一个地方管用户、管密码策略、管 MFA、管"谁能进哪个应用",所有服务共享同一套身份。

和自托管里别的"登录方案"定位对比:Authelia 等轻量反向代理认证更适合"给一堆子域名加一道统一登录墙";Keycloak 则是完整 IAM——支持标准协议(OIDC/SAML)、细粒度 realm/client/role、用户自助注册、MFA、与外部 IdP 联合等,适合"要正经做身份体系、接多个真正需要标准 SSO 的应用(如 Gitea、Nextcloud、Grafana 等)"的场景。规模越小、只想简单挡一道门,轻量方案可能更省;要标准协议与精细管理,Keycloak 是正解。

二、OIDC/SSO 基础:client、redirect、token 一次弄清

要让应用接入 Keycloak,先懂 OIDC 的最小骨架。几个词:Realm(领域,身份空间,一般一个自托管用一个)、Client(接入的应用,在 Keycloak 里注册一个 client 并给回调地址)、Authorization Code 流程(用户跳去 Keycloak 登录 → 拿 code 回应用 → 应用换 token)。SSO 的"一次登录到处用"来自共享会话:用户在 Keycloak 登录一次,其他接入的应用各自完成 code 交换时复用同一个会话,无需重复输密码。JWT 里的 claims(sub/email/roles)则让应用拿到用户信息与角色。

# 用 Docker 起 Keycloak(生产建议前接反代 HTTPS)
docker run -d --name keycloak --restart unless-stopped \
  -p 127.0.0.1:8080:8080 \
  -e KC_HOSTNAME=https://auth.example.com \
  -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
  -e KC_BOOTSTRAP_ADMIN_PASSWORD="强密码" \
  -v /srv/keycloak:/opt/keycloak/data \
  quay.io/keycloak/keycloak:25 start

# 接入应用(如 Grafana)的 OIDC 配置要点:
#   Auth URL:  https://auth.example.com/realms/你的Realm/protocol/openid-connect/auth
#   Token URL: https://auth.example.com/realms/你的Realm/protocol/openid-connect/token
#   Client ID / Secret: 在 Keycloak 的 Clients 里为 Grafana 建 client 时生成

排障时要分清"卡在认证前/认证中/回调后":登录页打不开多半是域名与反代没配好;code 换 token 失败多半是 client secret 或 redirect URI 不匹配;回调后拿不到用户信息多半是 client 的映射(claims)没配。把"realm → client → redirect → claims"这条链走通,OIDC 接入就顺了。

三、接反代与应用的三种方式:全站强制、应用原生 OIDC、网关级

自托管接入 Keycloak 有三条路线,按侵入程度排。一是"反代层强制登录":在 Nginx/Caddy 前面加一道 Keycloak 认证(如 oauth2-proxy),不登录不转发——适合"整个子域都要登录"的私有服务,应用本身不用改。二是"应用原生 OIDC":应用支持 Keycloak/OIDC(Grafana、Nextcloud、Gitea 等都支持),在应用配置里指向 Keycloak,身份最规范、能带角色。三是"网关级":让反代统一做认证并注入身份头,应用按头信任。多数人从"反代强制 + oauth2-proxy"起步,再用原生 OIDC 逐步替换支持的应用。

# 用 oauth2-proxy 在反代前加一道 Keycloak 登录(最小示意)
# oauth2-proxy --provider oidc \
#   --oidc-issuer-url=https://auth.example.com/realms/myrealm \
#   --client-id=oauth2-proxy --client-secret=xxxx \
#   --email-domain=* \
#   --upstream=http://127.0.0.1:3000
# Nginx 里把要保护的 location 先代理给 oauth2-proxy,通过后才转应用

建议的节奏:先"反代强制登录"把全站的门统一起来(最省事),再对支持原生 OIDC 的重要应用(Grafana/Gitea/Nextcloud)逐个切到原生协议——这样既有统一身份,又保留各应用的细粒度授权。别贪快一次全上原生,逐个验证更稳。

四、用户管理与 MFA:托管用户、密码策略、TOTP/WebAuthn

身份中心的管理能力是 Keycloak 相对轻量方案的核心优势:你可以在 Realm 里管用户(建、禁用、分组)、定密码策略(长度/复杂度/过期)、开启 MFA(TOTP 认证器或 WebAuthn 硬件密钥)、做用户自助注册与找回密码,还能接外部 IdP(如 GitHub 联合登录)让用户用已有账号登录。对"给家人朋友开访问"的场景,Keycloak 的"分组 + 角色"能按组给不同应用授权,管理与审计都有据可查。

# 常见管理动作(Admin Console 里,或 REST API)
#   用户:Users → Add user(设置初始密码/临时密码)
#   组:Groups → 建组 → 把用户加入 → 给组配角色
#   MFA:Authentication → Required actions 里启用 TOTP
#     → 用户下次登录被要求绑定认证器
#   密码策略:Authentication → Policies → Password policy
#     (如 length(12) 和 upperCase(1) 等)

管理要养成几个习惯:管理员账号用强密码 + MFA,别用默认 admin/admin;给外部用户开最小必要角色,定期清理不活跃账号;密码策略与 MFA 按"私有服务"与"暴露公网的服务"分级——公网暴露的强一点。Keycloak 的价值正在于"这些策略一次配置、全局生效",别浪费了它。

五、常见坑与边界:单点依赖、资源、备份与 OIDC 细节

Keycloak 落地,四个坑要防。一是"成了新单点":全站登录都靠它,它挂了所有人都登不进来——Keycloak 自身要跑稳(反代 HTTPS、健康检查、自动重启、数据库备份),并把它纳入高可用考虑。二是"资源":Keycloak 是 Java 应用,内存占用不小,别塞在只有 512MB 的小鸡里和别的服务挤。三是"数据库":Keycloak 把领域、用户、会话存数据库,务必备份;别用默认的 h2 就跑生产。四是"OIDC 细节":redirect URI 白名单要精确、HTTPS 要配好、密钥别外泄——否则要么回调失败,要么身份中心本身被攻破(它可是"全站的门")。

# 排障 SOP:接入失败先分层查
#   1) https://auth.example.com/realms/myrealm/.well-known/openid-configuration 能开吗
#   2) 应用里 client id/secret、redirect uri 与 Keycloak 里注册的完全一致吗
#   3) 登录后 code 换 token 报错?看 Keycloak 后台 Events 里的错误

把这几条当红线:Keycloak 是"全站身份的钥匙",它的高可用、备份、HTTPS、最小化管理权限都要按核心资产来对待——因为它一旦出问题,不是"某个应用登不了",而是"所有应用一起登不了"。

把 Keycloak 放回自托管整体:它是把"每个应用一套账号"收拢为"一个身份中心"的 IAM 基座。落地要点:用一个 Realm 管全站用户,给每个应用建独立 client 并走 OIDC code 流程;按"反代强制登录 → 原生 OIDC 逐个接入"的节奏推进;用分组/角色 + 密码策略 + MFA(TOTP/WebAuthn)把身份管理集中化;把它当核心资产——HTTPS、健康检查、数据库备份、管理员 MFA 一样不能少,并防住"成了新单点"与资源不足两坑。当所有服务共享同一个可信身份中心,自托管的"人"这一层才算被统一、可管、可审计地安顿下来。

结语

Keycloak 的价值,是给自托管一个标准的身份与访问管理中心:把分散的账号、密码、权限收拢成"一个 Realm 管全站用户",应用通过 OIDC 接入共享同一套认证与授权。落地要点:先起 Keycloak 并接好 HTTPS,建 realm/client 走通 code 流程;用 oauth2-proxy 在反代层先统一强制登录,再对支持原生 OIDC 的应用逐个切换;用分组/角色、密码策略、MFA 把用户与访问管起来;把它当核心资产配好备份、健康检查与管理员 MFA,防住单点与资源两坑。当你把"人"的身份集中到可信中心,自托管才算从"一堆各自为政的应用"升级为"一个统一可管的体系"。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

GitOps 实战:用 ArgoCD/Flux 把 K8s 部署交给 Git 做到可回退可重建

负载均衡算法深度实战:在 Nginx/HAProxy 上做好加权、最少连接与会话保持

评 论
更换验证码