<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Keycloak 实战配置与排错指南 — 解决方案 | IDaaS Book on IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/</link><description>Recent content in Keycloak 实战配置与排错指南 — 解决方案 | IDaaS Book on IDaaS Book</description><generator>Hugo</generator><language>zh-CN</language><copyright>Copyright (c) 2020-2024 xlabs.club</copyright><atom:link href="https://idaas.xlabs.club/docs/solution-blogs/index.xml" rel="self" type="application/rss+xml"/><item><title>Keycloak + oauth2-proxy 集成实战指南 | IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/keycloak-oauth2-proxy/</link><pubDate>Wed, 08 Jul 2026 00:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/docs/solution-blogs/keycloak-oauth2-proxy/</guid><description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;p&gt;你有一组内部 Web 应用（Grafana、Kibana、自研管理后台等），它们本身没有认证逻辑。你想用 Keycloak 做统一身份认证，用 oauth2-proxy 做反向代理层拦截所有未认证请求，在 Kubernetes 集群里通过 Nginx Ingress 暴露。&lt;/p&gt;
&lt;p&gt;一句话：&lt;strong&gt;Keycloak 负责「你是谁」，oauth2-proxy 负责「你能不能进这个应用」&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="适用与不适用"&gt;适用与不适用&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;适用&lt;/th&gt;
					&lt;th&gt;不适用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;内部工具统一认证（Grafana、Prometheus、Kibana）&lt;/td&gt;
					&lt;td&gt;需要细粒度授权的对外 API（用 BFF 或 API 网关）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;快速给老旧应用加 OIDC 登录&lt;/td&gt;
					&lt;td&gt;SPA 直连 Keycloak（不需要代理层）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;K8s Ingress 统一认证入口&lt;/td&gt;
					&lt;td&gt;需要 Keycloak Adapter 老项目的迁移目标（直接用标准 OIDC 库，参考 

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/keycloak-adapter-migration/"&gt;迁移指南&lt;/a&gt;）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;多个应用共享同一个 oauth2-proxy 实例&lt;/td&gt;
					&lt;td&gt;移动端 Native App（应该用系统浏览器 + PKCE）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="架构"&gt;架构&lt;/h2&gt;
&lt;pre class="mermaid"&gt;
 sequenceDiagram
 participant Browser as 浏览器
 participant Ingress as Nginx Ingress
 participant Proxy as oauth2-proxy
 participant App as 后端应用
 participant KC as Keycloak

 Browser-&amp;gt;&amp;gt;Ingress: GET /app
 Ingress-&amp;gt;&amp;gt;Proxy: auth-url /oauth2/auth
 Proxy--&amp;gt;&amp;gt;Ingress: 401 (未认证)
 Ingress-&amp;gt;&amp;gt;Browser: 302 → Keycloak 登录页
 Browser-&amp;gt;&amp;gt;KC: 登录
 KC--&amp;gt;&amp;gt;Browser: 302 → /oauth2/callback
 Browser-&amp;gt;&amp;gt;Proxy: GET /oauth2/callback?code=...
 Proxy-&amp;gt;&amp;gt;KC: Token 交换 (code → tokens)
 KC--&amp;gt;&amp;gt;Proxy: id_token + access_token + refresh_token
 Proxy--&amp;gt;&amp;gt;Browser: Set-Cookie (_oauth2_proxy) + 302 → /app
 Browser-&amp;gt;&amp;gt;Ingress: GET /app (带 Cookie)
 Ingress-&amp;gt;&amp;gt;Proxy: auth-url (带 Cookie)
 Proxy--&amp;gt;&amp;gt;Ingress: 202 (已认证)
 Ingress-&amp;gt;&amp;gt;App: 代理请求 + X-Auth-Request-* Headers
 App--&amp;gt;&amp;gt;Browser: 200 OK
&lt;/pre&gt;

&lt;p&gt;流程要点：&lt;/p&gt;</description></item><item><title>Keycloak 重定向循环与 401 排错指南 | IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/keycloak-redirect-loop-troubleshooting/</link><pubDate>Wed, 08 Jul 2026 00:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/docs/solution-blogs/keycloak-redirect-loop-troubleshooting/</guid><description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;p&gt;你已经部署好了 Keycloak +反向代理，用户能在 Keycloak 登录页输入用户名密码，但登录成功后浏览器在 Keycloak 和应用之间反复跳转，最终浏览器报 &lt;code&gt;ERR_TOO_MANY_REDIRECTS&lt;/code&gt;；或者直接返回 401，看起来&amp;quot;登录成功了但就是进不去&amp;quot;。&lt;/p&gt;
&lt;p&gt;这类问题的根因几乎都在 &lt;strong&gt;Cookie、反向代理 Header、TLS 终结 和 OIDC 回调 URI&lt;/strong&gt; 四个环节。本文给出一个系统性的排查路线图。&lt;/p&gt;
&lt;h2 id="适用与不适用"&gt;适用与不适用&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;适用&lt;/th&gt;
					&lt;th&gt;不适用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Keycloak + 任意反向代理（Nginx/Traefik/HAProxy/ALB）&lt;/td&gt;
					&lt;td&gt;Keycloak 本身无法启动（那是部署问题）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;oauth2-proxy / Traefik ForwardAuth / Nginx auth-url 模式&lt;/td&gt;
					&lt;td&gt;用户凭据错误（先确认用户名密码正确）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;OIDC 标准客户端（非 Keycloak Adapter）&lt;/td&gt;
					&lt;td&gt;Keycloak Adapter 老项目（Adapters 已弃用，参考 

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/keycloak-adapter-migration/"&gt;迁移指南&lt;/a&gt; 迁移到标准 OIDC 库再排查）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SAML 单点登录重定向问题&lt;/td&gt;
					&lt;td&gt;纯 LDAP/Kerberos 认证（不涉及 HTTP 重定向）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="排查路线图"&gt;排查路线图&lt;/h2&gt;
&lt;pre class="mermaid"&gt;
 flowchart TD
 A[用户登录后重定向循环 / 401] --&amp;gt; B{反向代理配置是否正确？}
 B --&amp;gt;|否| B1[X-Forwarded-For / X-Forwarded-Proto 缺失]
 B --&amp;gt;|是| C{Cookie 是否能写入浏览器？}
 C --&amp;gt;|否| C1[SameSite 过严 / Domain 不匹配 / Secure 标记与 HTTP 冲突]
 C --&amp;gt;|是| D{OIDC 回调 URI 是否匹配？}
 D --&amp;gt;|否| D1[redirect_uri 拼写错误 / 协议不匹配 / 端口不一致]
 D --&amp;gt;|是| E{TLS 终结在哪一层？}
 E --&amp;gt;|错层| E1[代理层 HTTP → Keycloak 看到 HTTP 而非 HTTPS]
 E --&amp;gt;|正确| F{认证后的 Token 校验？}
 F --&amp;gt;|失败| F1[audience / issuer / nbf 校验失败]
 F --&amp;gt;|通过| G[✅ 认证链路正常，检查应用层逻辑]
&lt;/pre&gt;

&lt;h2 id="第一关反向代理-header"&gt;第一关：反向代理 Header&lt;/h2&gt;
&lt;p&gt;Keycloak 自身不面向公网时，反向代理必须正确传递三个 Header，否则 Keycloak 构建的重定向 URL 会出错。&lt;/p&gt;</description></item><item><title>IAM 网关 oauth2-proxy 常见错误排错 | IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/</link><pubDate>Mon, 13 Jul 2026 00:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/</guid><description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;p&gt;你按照文档配好了 oauth2-proxy + Keycloak，部署到 Kubernetes，打开浏览器——白屏、401、无限跳转、或者 &amp;ldquo;csrf cookie not found&amp;rdquo;。这些错误 oauth2-proxy 的日志里写得很直白，但&lt;strong&gt;为什么发生、怎么修&lt;/strong&gt;才是真正的卡点。&lt;/p&gt;
&lt;p&gt;这篇文章把 GitHub Issues 和 Stack Overflow 上反复出现的高频错误整理成速查表：每条有诊断命令、根因分析、修复步骤。不需要逐条 Google——直接对号入座。&lt;/p&gt;
&lt;p&gt;适用：oauth2-proxy v7.x + Keycloak（任意版本），auth-url 或 ForwardAuth 模式。&lt;/p&gt;
&lt;p&gt;不适用：oauth2-proxy 旧版（v6 及以下，部分参数名不同）、非 Keycloak Provider（GitHub/Google 等 Provider 有各自特有的错误）。&lt;/p&gt;
&lt;h2 id="错误速查导航"&gt;错误速查导航&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;错误关键词&lt;/th&gt;
					&lt;th&gt;出现阶段&lt;/th&gt;
					&lt;th&gt;严重程度&lt;/th&gt;
					&lt;th&gt;跳转&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;csrf cookie not found&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;登录回调&lt;/td&gt;
					&lt;td&gt;🔴 阻断&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#1-csrf-cookie-not-found"&gt;错误 1&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;expected audience&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Token 校验&lt;/td&gt;
					&lt;td&gt;🔴 阻断&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#2-expected-audience-got-account"&gt;错误 2&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;redirect loop&lt;/code&gt; / &lt;code&gt;ERR_TOO_MANY_REDIRECTS&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;登录后&lt;/td&gt;
					&lt;td&gt;🔴 阻断&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#3-登录后无限重定向-redirect-loop"&gt;错误 3&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;invalid_token&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Token 校验&lt;/td&gt;
					&lt;td&gt;🔴 阻断&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#4-invalid_token"&gt;错误 4&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;missing state parameter&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;登录回调&lt;/td&gt;
					&lt;td&gt;🔴 阻断&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#5-missing-state-parameter"&gt;错误 5&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;cookie too large&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;登录回调&lt;/td&gt;
					&lt;td&gt;🟡 部分用户&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#6-cookie-too-large"&gt;错误 6&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;401&lt;/code&gt; 已登录却被拒&lt;/td&gt;
					&lt;td&gt;请求阶段&lt;/td&gt;
					&lt;td&gt;🟡 间歇性&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#7-401-已登录但认证被拒"&gt;错误 7&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;could not get claim: missing claim &amp;quot;email&amp;quot;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Token 校验&lt;/td&gt;
					&lt;td&gt;🟡 特定用户&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#8-missing-claim-email"&gt;错误 8&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;error=access_denied&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Keycloak 端&lt;/td&gt;
					&lt;td&gt;🟡 配置&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#9-erroraccess_denied"&gt;错误 9&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Nginx 503&lt;/code&gt; / &lt;code&gt;no live upstreams&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;请求阶段&lt;/td&gt;
					&lt;td&gt;🟡 基础设施&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#10-nginx-ingress-返回-503"&gt;错误 10&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Cookie 只在主域名生效，子域名不行&lt;/td&gt;
					&lt;td&gt;跨子域&lt;/td&gt;
					&lt;td&gt;🟡 配置&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#11-cookie-跨子域不生效"&gt;错误 11&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;登出一个应用导致全部退出&lt;/td&gt;
					&lt;td&gt;共享 session&lt;/td&gt;
					&lt;td&gt;🟢 体验&lt;/td&gt;
					&lt;td&gt;

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/oauth2-proxy-common-errors/#12-登出一个应用全部退出"&gt;错误 12&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="1-csrf-cookie-not-found"&gt;1. csrf cookie not found&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;日志典型输出&lt;/strong&gt;：&lt;/p&gt;</description></item><item><title>Keycloak LDAP / Active Directory 用户联邦 — 配置、同步与排错 | IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/keycloak-ldap-ad-federation/</link><pubDate>Thu, 09 Jul 2026 00:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/docs/solution-blogs/keycloak-ldap-ad-federation/</guid><description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;p&gt;你所在的企业已经用 Active Directory 或 OpenLDAP 管理员工账号多年。现在引入 Keycloak 做统一认证，但不可能把所有用户手动迁移到 Keycloak 本地数据库——需要 Keycloak 直接对接现有的 LDAP/AD，让用户用域账号登录，管理员在原系统维护用户。&lt;/p&gt;
&lt;p&gt;一句话：&lt;strong&gt;LDAP/AD 是权威用户源，Keycloak 消费但不拥有这些用户&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="适用--不适用"&gt;适用 / 不适用&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;适用场景&lt;/th&gt;
					&lt;th&gt;不适用场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;企业已有 AD/LDAP，不能动用户库&lt;/td&gt;
					&lt;td&gt;新建系统、无遗留目录服务（直接用 Keycloak 本地用户即可）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;需要 LDAP 用户和 Keycloak 本地用户混合认证&lt;/td&gt;
					&lt;td&gt;需要 Keycloak 写入 LDAP（User Federation 默认只读同步）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;多个 Realm 共享同一个 LDAP 源&lt;/td&gt;
					&lt;td&gt;LDAP schema 与标准差异极大、需要大量自定义逻辑&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="最小配置"&gt;最小配置&lt;/h2&gt;
&lt;h3 id="keycloak-侧添加-ldap-user-federation"&gt;Keycloak 侧：添加 LDAP User Federation&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;进入目标 Realm → &lt;strong&gt;User federation&lt;/strong&gt; → &lt;strong&gt;Add Ldap provider&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;填写连接参数（以 AD 为例，OpenLDAP 见下节差异表）：&lt;/li&gt;
&lt;/ol&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;参数&lt;/th&gt;
					&lt;th&gt;示例值 (AD)&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Vendor&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Active Directory&lt;/td&gt;
					&lt;td&gt;选择 &lt;code&gt;Active Directory&lt;/code&gt; 后 Keycloak 会自动调整部分默认值&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Connection URL&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;ldaps://dc.example.com:636&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;生产必须用 LDAPS（端口 636），不要用裸 LDAP&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Bind DN&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;CN=svc_keycloak,CN=Users,DC=example,DC=com&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;专用服务账号，不要用域管理员&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Bind Credential&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;服务账号密码&lt;/td&gt;
					&lt;td&gt;使用 &lt;code&gt;vault&lt;/code&gt; / Kubernetes Secret 注入，别写死在配置里&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Users DN&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;CN=Users,DC=example,DC=com&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;LDAP 中存放用户条目的基础 DN&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Edit Mode&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;READ_ONLY&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;生产环境必须 READ_ONLY，避免 Keycloak 侧修改污染 LDAP&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ol start="3"&gt;
&lt;li&gt;配置用户搜索：&lt;/li&gt;
&lt;/ol&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;参数&lt;/th&gt;
					&lt;th&gt;值&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Username LDAP attribute&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;sAMAccountName&lt;/code&gt; (AD) / &lt;code&gt;uid&lt;/code&gt; (OpenLDAP)&lt;/td&gt;
					&lt;td&gt;作为 Keycloak 用户名的 LDAP 属性&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RDN LDAP attribute&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;cn&lt;/code&gt; (AD) / &lt;code&gt;uid&lt;/code&gt; (OpenLDAP)&lt;/td&gt;
					&lt;td&gt;条目的命名属性&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;UUID LDAP attribute&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;objectGUID&lt;/code&gt; (AD) / &lt;code&gt;entryUUID&lt;/code&gt; (OpenLDAP)&lt;/td&gt;
					&lt;td&gt;不可变的唯一标识，用于追踪用户&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;User Object Classes&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;person, organizationalPerson, user&lt;/code&gt; (AD) / &lt;code&gt;inetOrgPerson, organizationalPerson&lt;/code&gt; (OpenLDAP)&lt;/td&gt;
					&lt;td&gt;过滤用户条目的 objectClass&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ol start="4"&gt;
&lt;li&gt;可选：LDAP 过滤器限制同步范围：&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="expressive-code"&gt;
 &lt;figure class="frame not-content"&gt;
 &lt;figcaption class="header"&gt;
 &lt;span class="title"&gt;&lt;/span&gt;
 &lt;/figcaption&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt;# 只同步 IT 部门的启用用户
(&amp;amp;(objectCategory=person)(department=IT)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))&lt;/code&gt;&lt;/pre&gt;
 &lt;/figure&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;过滤器里的 &lt;code&gt;userAccountControl:1.2.840.113556.1.4.803:=2&lt;/code&gt; 是 AD 中标志“禁用账户”的位运算写法。生产环境务必过滤掉禁用账户，否则离职员工仍可通过 LDAP 同步拥有 Keycloak 账号。&lt;/p&gt;</description></item><item><title>Keycloak Prometheus 监控指标详解 — 启用、采集与告警 | IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/keycloak-prometheus-metrics/</link><pubDate>Thu, 09 Jul 2026 00:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/docs/solution-blogs/keycloak-prometheus-metrics/</guid><description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;p&gt;你把 Keycloak 部署到生产环境（Kubernetes 或裸机），Pod 在跑、用户能登录——但发生问题时只能一个个看日志，不知道是数据库慢了、JVM 内存快满了、还是某条认证链路在掉请求。&lt;/p&gt;
&lt;p&gt;你需要一套开箱即用的 Prometheus + Grafana 可观测方案：知道该采集哪些指标、哪些指标对应什么运维动作、告警阈值怎么设。&lt;/p&gt;
&lt;h2 id="适用--不适用"&gt;适用 / 不适用&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;适用&lt;/th&gt;
					&lt;th&gt;不适用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Keycloak 22+（Quarkus 发行版，Micrometer 指标）&lt;/td&gt;
					&lt;td&gt;Keycloak &amp;lt; 22（WildFly 版本使用不同的指标名）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;已有 Prometheus/Grafana 体系&lt;/td&gt;
					&lt;td&gt;没有 Prometheus 基础（需要先搭建监控栈）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Kubernetes Operator / Helm / 裸机部署&lt;/td&gt;
					&lt;td&gt;仅想通过 Keycloak Admin UI 看运行状态&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;Keycloak 22 从 WildFly 迁移到 Quarkus 后，指标体系改用了 Micrometer，旧版 Grafana Dashboard（如 ID 10441）的指标名不再适用。如果你的 Keycloak 是 WildFly 版本，指标路径为 &lt;code&gt;/auth/realms/master/metrics&lt;/code&gt;，且指标名以 &lt;code&gt;keycloak_&lt;/code&gt; 为前缀。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="启用-metrics"&gt;启用 Metrics&lt;/h2&gt;
&lt;h3 id="方式一cli-启动参数"&gt;方式一：CLI 启动参数&lt;/h3&gt;



&lt;div class="expressive-code"&gt;
 &lt;figure class="frame is-terminal not-content"&gt;
 &lt;figcaption class="header"&gt;
 &lt;span class="title"&gt;&lt;/span&gt;
 &lt;/figcaption&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kc.sh start --metrics-enabled&lt;span class="o"&gt;=&lt;/span&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;/figure&gt;
&lt;/div&gt;
&lt;h3 id="方式二环境变量"&gt;方式二：环境变量&lt;/h3&gt;



&lt;div class="expressive-code"&gt;
 &lt;figure class="frame is-terminal not-content"&gt;
 &lt;figcaption class="header"&gt;
 &lt;span class="title"&gt;&lt;/span&gt;
 &lt;/figcaption&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;KC_METRICS_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;/figure&gt;
&lt;/div&gt;
&lt;h3 id="方式三confkeycloakconf"&gt;方式三：conf/keycloak.conf&lt;/h3&gt;



&lt;div class="expressive-code"&gt;
 &lt;figure class="frame not-content"&gt;
 &lt;figcaption class="header"&gt;
 &lt;span class="title"&gt;&lt;/span&gt;
 &lt;/figcaption&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt;metrics-enabled=true&lt;/code&gt;&lt;/pre&gt;
 &lt;/figure&gt;
&lt;/div&gt;
&lt;h3 id="方式四kubernetes-operator-cr"&gt;方式四：Kubernetes Operator CR&lt;/h3&gt;



&lt;div class="expressive-code"&gt;
 &lt;figure class="frame not-content"&gt;
 &lt;figcaption class="header"&gt;
 &lt;span class="title"&gt;&lt;/span&gt;
 &lt;/figcaption&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;additionalOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;metrics-enabled&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;/figure&gt;
&lt;/div&gt;
&lt;h3 id="方式五helm"&gt;方式五：Helm&lt;/h3&gt;



&lt;div class="expressive-code"&gt;
 &lt;figure class="frame is-terminal not-content"&gt;
 &lt;figcaption class="header"&gt;
 &lt;span class="title"&gt;&lt;/span&gt;
 &lt;/figcaption&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm install keycloak bitnami/keycloak --set metrics.enabled&lt;span class="o"&gt;=&lt;/span&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;/figure&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;metrics-enabled&lt;/code&gt; 是构建时（build-time）选项，必须在首次启动时或通过 &lt;code&gt;kc.sh build&lt;/code&gt; 阶段指定。如果你通过 Operator 或 conf 文件修改了此选项但没重建，需要先 &lt;code&gt;kc.sh build&lt;/code&gt; 或重启 Pod 使其生效。&lt;/p&gt;</description></item><item><title>Keycloak 高可用集群部署与灾难恢复实战 | IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/keycloak-ha-dr/</link><pubDate>Thu, 09 Jul 2026 00:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/docs/solution-blogs/keycloak-ha-dr/</guid><description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;p&gt;你在生产环境跑着单节点的 Keycloak，业务方已经依赖它完成 SSO 登录。某天凌晨数据库挂了、节点 OOM 重启了，或者 Kubernetes Node 被 drain 了——所有依赖 Keycloak 的应用全部掉线。&lt;/p&gt;
&lt;p&gt;你需要在故障发生前就把集群搭好，并且有一套经过演练的备份恢复流程。&lt;/p&gt;
&lt;p&gt;本文不重复 

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/implementation/kubernetes-production/"&gt;Keycloak Kubernetes 生产部署&lt;/a&gt; 的完整 Operator 部署步骤，而是聚焦三个核心问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;多节点集群怎么配才能&lt;strong&gt;不丢 Session、不断登录&lt;/strong&gt;？&lt;/li&gt;
&lt;li&gt;数据库备份怎么做到&lt;strong&gt;可验证恢复&lt;/strong&gt;而不仅仅是&amp;quot;dump 了&amp;quot;？&lt;/li&gt;
&lt;li&gt;故障发生时的&lt;strong&gt;恢复步骤&lt;/strong&gt;和&lt;strong&gt;回滚路径&lt;/strong&gt;是什么？&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="适用与不适用"&gt;适用与不适用&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;适用&lt;/th&gt;
					&lt;th&gt;不适用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Keycloak 24+ 基于 Quarkus 发行版&lt;/td&gt;
					&lt;td&gt;旧版 WildFly 发行版（集群配置不同）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;生产环境需要 HA 和灾难恢复&lt;/td&gt;
					&lt;td&gt;开发环境单节点即可&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Kubernetes（Operator/Helm）或裸机部署&lt;/td&gt;
					&lt;td&gt;刚接触 Keycloak、还未完成单节点部署&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PostgreSQL/MySQL 等外部数据库&lt;/td&gt;
					&lt;td&gt;内嵌 H2 数据库（不可用于集群或生产）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="集群架构概览"&gt;集群架构概览&lt;/h2&gt;
&lt;p&gt;Keycloak 集群的核心依赖只有两个：&lt;strong&gt;共享数据库&lt;/strong&gt; + &lt;strong&gt;节点发现机制&lt;/strong&gt;。没有共享存储、没有共享 Session 文件。&lt;/p&gt;
&lt;pre class="mermaid"&gt;
 graph TB
 LB[负载均衡器&amp;lt;br/&amp;gt;Nginx/ALB/HAProxy]
 
 subgraph KC1[Keycloak 节点 1]
 KC1_APP[Keycloak 26.x&amp;lt;br/&amp;gt;Quarkus]
 KC1_CACHE[InfiniSpan Cache&amp;lt;br/&amp;gt;Sessions/ClientSessions]
 end
 
 subgraph KC2[Keycloak 节点 2]
 KC2_APP[Keycloak 26.x&amp;lt;br/&amp;gt;Quarkus]
 KC2_CACHE[InfiniSpan Cache&amp;lt;br/&amp;gt;Sessions/ClientSessions]
 end
 
 DB[(PostgreSQL&amp;lt;br/&amp;gt;共享数据库)]
 
 LB --&amp;gt; KC1_APP
 LB --&amp;gt; KC2_APP
 KC1_APP --&amp;gt; DB
 KC2_APP --&amp;gt; DB
 KC1_CACHE &amp;lt;--&amp;gt;|JGroups 分布式缓存| KC2_CACHE
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;关键理解&lt;/strong&gt;：Keycloak 的 Session 数据存在两个地方——数据库是持久化的（离线 token、持久 session），InfiniSpan 分布式缓存是内存/近缓存（在线 session）。节点挂了，在线 session 从其他节点的 InfiniSpan 缓存中恢复；如果整个集群都挂了，持久化的 session 从数据库恢复。&lt;/p&gt;</description></item><item><title>Keycloak 集群缓存深度调优与排错指南 | IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/keycloak-cluster-cache-tuning/</link><pubDate>Fri, 10 Jul 2026 00:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/docs/solution-blogs/keycloak-cluster-cache-tuning/</guid><description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;p&gt;你已经按 

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/keycloak-ha-dr/"&gt;Keycloak 高可用集群部署&lt;/a&gt; 把两个以上的 Keycloak 节点跑起来了，负载均衡器也配好了。但上线后开始遇到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户登录后刷新页面跳到另一个节点，又弹回登录页——Session 丢了&lt;/li&gt;
&lt;li&gt;集群日志里频繁出现 &lt;code&gt;SuspectException&lt;/code&gt; 或 &lt;code&gt;JGRP000006: failed accepting connection&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;改了 Realm 配置，另一个节点几分钟后才生效&lt;/li&gt;
&lt;li&gt;内存占用持续增长，JVM GC 频繁，怀疑缓存没设上限&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些问题根因都在 &lt;strong&gt;Infinispan 分布式缓存层&lt;/strong&gt;。本文不重复集群部署步骤，只聚焦缓存层的配置、调优和排错。&lt;/p&gt;
&lt;h2 id="适用与不适用"&gt;适用与不适用&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;适用&lt;/th&gt;
					&lt;th&gt;不适用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Keycloak 24+ Quarkus 发行版，集群模式&lt;/td&gt;
					&lt;td&gt;开发模式（&lt;code&gt;start-dev&lt;/code&gt;，只有本地缓存）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;2 个以上节点组成集群&lt;/td&gt;
					&lt;td&gt;单节点部署&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;需要理解 &lt;code&gt;cache-ispn.xml&lt;/code&gt; 或排查缓存相关问题&lt;/td&gt;
					&lt;td&gt;不需要集群、只用默认配置就能跑&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;使用 &lt;code&gt;jdbc-ping&lt;/code&gt;、&lt;code&gt;DNS_PING&lt;/code&gt; 等传输栈&lt;/td&gt;
					&lt;td&gt;WildFly 旧版 Keycloak（配置路径不同）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="keycloak-缓存架构全景"&gt;Keycloak 缓存架构全景&lt;/h2&gt;
&lt;p&gt;Keycloak 的缓存层由 Infinispan 驱动，按数据特性分为三种缓存类型：&lt;/p&gt;
&lt;pre class="mermaid"&gt;
 graph TB
 subgraph &amp;#34;Keycloak 节点 A&amp;#34;
 LOCAL_A[&amp;#34;Local 缓存&amp;lt;br/&amp;gt;realms / users / authorization / keys / crl&amp;#34;]
 DIST_A[&amp;#34;Distributed 缓存&amp;lt;br/&amp;gt;sessions / clientSessions / authenticationSessions&amp;#34;]
 REPL_A[&amp;#34;Replicated 缓存&amp;lt;br/&amp;gt;work（失效消息）&amp;#34;]
 end

 subgraph &amp;#34;Keycloak 节点 B&amp;#34;
 LOCAL_B[&amp;#34;Local 缓存&amp;lt;br/&amp;gt;realms / users / authorization / keys / crl&amp;#34;]
 DIST_B[&amp;#34;Distributed 缓存&amp;lt;br/&amp;gt;sessions / clientSessions / authenticationSessions&amp;#34;]
 REPL_B[&amp;#34;Replicated 缓存&amp;lt;br/&amp;gt;work（失效消息）&amp;#34;]
 end

 DB[(PostgreSQL/MySQL&amp;lt;br/&amp;gt;持久化存储)]

 DIST_A &amp;lt;--&amp;gt;|&amp;#34;JGroups 同步&amp;lt;br/&amp;gt;每个 Entry 1-2 个 owner&amp;#34;| DIST_B
 REPL_A &amp;lt;--&amp;gt;|&amp;#34;JGroups 同步&amp;lt;br/&amp;gt;所有节点全量拷贝&amp;#34;| REPL_B
 LOCAL_A -.-&amp;gt;|&amp;#34;失效消息触发刷新&amp;#34;| LOCAL_B
 LOCAL_A --&amp;gt; DB
 LOCAL_B --&amp;gt; DB
 DIST_A --&amp;gt; DB
 DIST_B --&amp;gt; DB
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;三种缓存类型说明&lt;/strong&gt;：&lt;/p&gt;</description></item><item><title>Keycloak 细粒度权限与授权策略实战 — Groups vs Roles、Authorization Services | IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/keycloak-fine-grained-authz/</link><pubDate>Thu, 09 Jul 2026 00:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/docs/solution-blogs/keycloak-fine-grained-authz/</guid><description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;p&gt;你已经在 Keycloak 里配好了 Realm、Client 和用户，SSO 登录也跑通了。现在业务方提了三个需求：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&amp;ldquo;这个 API 只有管理员能调，普通用户不行&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;同一个 API，部门 A 的人能写、部门 B 的人只能读&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;用户可以查看自己的订单，但不能看别人的&amp;rdquo;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;你在 Keycloak 的 Groups、Roles、Composite Roles、Authorization Services 之间绕晕了——到底该用哪个？配了半天 Policy Evaluation 还是不通过。&lt;/p&gt;
&lt;h2 id="适用与不适用"&gt;适用与不适用&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;适用&lt;/th&gt;
					&lt;th&gt;不适用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;需要对单个资源做细粒度控制（按 HTTP 方法、URI、资源属性）&lt;/td&gt;
					&lt;td&gt;只需要简单的「已登录/未登录」判断&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;多个应用共用 Keycloak，授权规则各不相同&lt;/td&gt;
					&lt;td&gt;授权规则完全由应用内部代码管理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;需要 ABAC/ReBAC 混合模型&lt;/td&gt;
					&lt;td&gt;只需要 OAuth 2.0 Scope 就够了&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;有管理后台需要按角色区分菜单可见性&lt;/td&gt;
					&lt;td&gt;你的应用根本不区分角色&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="核心概念速览"&gt;核心概念速览&lt;/h2&gt;
&lt;p&gt;在深入配置之前，先理清几个最容易混淆的概念：&lt;/p&gt;
&lt;h3 id="group-vs-role"&gt;Group vs Role&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;/th&gt;
					&lt;th&gt;Group&lt;/th&gt;
					&lt;th&gt;Role&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;本质&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;用户的组织归属&lt;/td&gt;
					&lt;td&gt;用户的权限标签&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;典型值&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;engineering&lt;/code&gt;、&lt;code&gt;sales&lt;/code&gt;、&lt;code&gt;cn-team&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;admin&lt;/code&gt;、&lt;code&gt;viewer&lt;/code&gt;、&lt;code&gt;order-manager&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;能嵌套吗&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;✅ 支持子 Group&lt;/td&gt;
					&lt;td&gt;✅ 通过 Composite Role 嵌套&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;适合干什么&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;按部门/团队分组、LDAP 映射&lt;/td&gt;
					&lt;td&gt;授予具体权限、做 RBAC&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;不适合干什么&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;直接做权限判断&lt;/td&gt;
					&lt;td&gt;表达部门层级关系&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;简单原则&lt;/strong&gt;：Group 说「你是谁的人」，Role 说「你能干什么」。一个用户可以有多个 Group 和多个 Role。&lt;/p&gt;</description></item><item><title>Traefik ForwardAuth + Keycloak + oauth2-proxy 完整配置与排错指南 | IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/traefik-forwardauth-keycloak/</link><pubDate>Thu, 09 Jul 2026 00:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/docs/solution-blogs/traefik-forwardauth-keycloak/</guid><description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;p&gt;你用 Traefik 做 Kubernetes Ingress Controller，用 Keycloak 做统一身份认证，现在有一组内部 Web 应用需要加登录保护。不想在每个应用里改代码接 OIDC，想在入口层解决问题。&lt;/p&gt;
&lt;p&gt;一句话：&lt;strong&gt;Traefik ForwardAuth 中间件指向 oauth2-proxy，oauth2-proxy 对接 Keycloak——三个组件各司其职，入口层统一认证。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="适用与不适用"&gt;适用与不适用&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;适用&lt;/th&gt;
					&lt;th&gt;不适用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;已使用 Traefik 作为 Ingress Controller 的 K8s 集群&lt;/td&gt;
					&lt;td&gt;使用 Nginx Ingress Controller（参考 

&lt;a class="link link--text" href="https://idaas.xlabs.club/docs/solution-blogs/keycloak-oauth2-proxy/"&gt;Keycloak + oauth2-proxy 集成指南&lt;/a&gt; 的 auth-url 模式）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;需要给多个内部工具统一加 OIDC 登录（Grafana、Kibana、Argo CD）&lt;/td&gt;
					&lt;td&gt;SPA 直连 Keycloak（不需要代理层）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;需要链式中间件（限流 + 认证 + 头改写）&lt;/td&gt;
					&lt;td&gt;需要细粒度路径级授权（用 Pomerium 或 API 网关）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;已有 Traefik EntryPoint 做 TLS 终结&lt;/td&gt;
					&lt;td&gt;移动端 Native App（用系统浏览器 + PKCE）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="架构"&gt;架构&lt;/h2&gt;
&lt;pre class="mermaid"&gt;
 sequenceDiagram
 participant Browser as 浏览器
 participant Traefik as Traefik&amp;lt;br/&amp;gt;(Ingress Controller)
 participant Proxy as oauth2-proxy
 participant KC as Keycloak
 participant App as 后端应用

 Note over Browser,App: 首次访问（无 Cookie）
 Browser-&amp;gt;&amp;gt;Traefik: GET /app (TLS)
 Traefik-&amp;gt;&amp;gt;Proxy: ForwardAuth GET /oauth2/auth
 Proxy--&amp;gt;&amp;gt;Traefik: 401 Unauthorized
 Traefik-&amp;gt;&amp;gt;Browser: 302 → Keycloak 登录页

 Note over Browser,App: 用户在 Keycloak 完成登录
 Browser-&amp;gt;&amp;gt;KC: 输入凭据 + 登录
 KC--&amp;gt;&amp;gt;Browser: 302 → /oauth2/callback?code=xxx&amp;amp;state=yyy

 Note over Browser,App: oauth2-proxy 回调
 Browser-&amp;gt;&amp;gt;Traefik: GET /oauth2/callback
 Traefik-&amp;gt;&amp;gt;Proxy: ForwardAuth 放行（callback 路径不拦截）
 Proxy-&amp;gt;&amp;gt;KC: POST /token (code 换 token)
 KC--&amp;gt;&amp;gt;Proxy: access_token + id_token
 Proxy--&amp;gt;&amp;gt;Browser: Set-Cookie + 302 → /app

 Note over Browser,App: 二次访问（带 Cookie）
 Browser-&amp;gt;&amp;gt;Traefik: GET /app (带 _oauth2_proxy Cookie)
 Traefik-&amp;gt;&amp;gt;Proxy: ForwardAuth GET /oauth2/auth
 Proxy--&amp;gt;&amp;gt;Traefik: 202 Accepted
 Traefik-&amp;gt;&amp;gt;App: GET /app (透传 X-Auth-Request-* 头)
 App--&amp;gt;&amp;gt;Browser: 200 OK
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：&lt;/p&gt;</description></item><item><title>Dex + Keycloak 联合身份：Kubernetes 集群 OIDC 认证集成 | IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/dex-keycloak-federation/</link><pubDate>Thu, 09 Jul 2026 00:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/docs/solution-blogs/dex-keycloak-federation/</guid><description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;p&gt;组织用 Keycloak 管理全部用户和组（对接 AD/LDAP 或本地用户），同时需要为多个 Kubernetes 集群提供统一身份认证。直接在 Kubernetes API Server 挂 Keycloak 做 OIDC 可行，但有两个常见痛点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;多集群管理&lt;/strong&gt;：每个集群的 API Server 需要指向同一个 issuer URL，Keycloak 的 realm 级别 issuer 不够灵活&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上游身份源复用&lt;/strong&gt;：Keycloak 本身对接了 AD、LDAP、GitHub 等多个 IdP，Kubernetes 还想同时接受这些来源的用户&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这时 Dex 作为 OIDC 代理层，Keycloak 作为上游身份源，是最成熟的生产组合。&lt;/p&gt;
&lt;p&gt;一句话：&lt;strong&gt;Keycloak 管你是谁，Dex 把你的身份转换成 Kubernetes 认识的 OIDC&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="适用场景"&gt;适用场景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;已有 Keycloak 部署，需要给 Kubernetes 加 OIDC 认证&lt;/li&gt;
&lt;li&gt;多个 Kubernetes 集群需要共享同一套身份&lt;/li&gt;
&lt;li&gt;需要 Keycloak 的用户组映射到 Kubernetes RBAC 的 groups claim&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="不适用场景"&gt;不适用场景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;没有 Keycloak，只想用 Dex 直连 LDAP/AD —— 直接在 Dex 配 LDAP connector 即可&lt;/li&gt;
&lt;li&gt;只有一个小集群且用户都在 Keycloak 本地 —— 可以考虑直接对接 Keycloak OIDC&lt;/li&gt;
&lt;li&gt;需要 Kubernetes 之外的完整 IAM 能力——直接用 Keycloak，不需要 Dex&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="架构"&gt;架构&lt;/h2&gt;
&lt;pre class="mermaid"&gt;
 sequenceDiagram
 participant User as kubectl / kubelogin
 participant K8s as Kubernetes API Server
 participant Dex as Dex&amp;lt;br/&amp;gt;(OIDC Provider)
 participant KC as Keycloak&amp;lt;br/&amp;gt;(上游 OIDC Provider)

 User-&amp;gt;&amp;gt;K8s: kubectl 请求
 K8s-&amp;gt;&amp;gt;User: 401 + OIDC redirect
 User-&amp;gt;&amp;gt;Dex: 浏览器打开 Dex 登录页
 Dex-&amp;gt;&amp;gt;KC: OIDC Authorization Code Flow&amp;lt;br/&amp;gt;(redirect 到 Keycloak 登录页)
 KC-&amp;gt;&amp;gt;User: 登录表单 / SSO session
 User-&amp;gt;&amp;gt;KC: 用户名+密码 / 已有 session
 KC-&amp;gt;&amp;gt;Dex: Authorization Code
 Dex-&amp;gt;&amp;gt;KC: Token Request&amp;lt;br/&amp;gt;(client_id + client_secret)
 KC-&amp;gt;&amp;gt;Dex: ID Token + Access Token
 Dex-&amp;gt;&amp;gt;Dex: 提取 claims (sub, email, groups)&amp;lt;br/&amp;gt;生成 Dex 自己的 ID Token
 Dex-&amp;gt;&amp;gt;User: Dex ID Token
 User-&amp;gt;&amp;gt;K8s: Bearer Token (Dex ID Token)
 K8s-&amp;gt;&amp;gt;K8s: 验证 JWT 签名、issuer、audience
 K8s-&amp;gt;&amp;gt;User: kubectl 执行结果
&lt;/pre&gt;

&lt;p&gt;核心链路：&lt;strong&gt;kubectl/kubelogin → Dex（OIDC Provider）→ Keycloak（上游 OIDC 源）→ AD/LDAP/本地用户&lt;/strong&gt;。&lt;/p&gt;</description></item></channel></rss>