IAM 网关实战配置与排错指南 | IDaaS Book
这部分是「带着问题来,拿着方案走」的实战指南。每篇文章聚焦一个具体的集成场景:出问题怎么办、最小配置怎么写、怎么验证配对了、配错了什么症状、怎么回滚。
与前面章节的理论和架构介绍不同,这里的文章结构统一为:场景描述 → 适用/不适用 → 最小配置 → 验证 → 常见错误表 → 回滚方式。
按场景直达:
- 入口网关选型:
Envoy Gateway 原生 OIDC(Gateway API)、
APISIX openid-connect(网关插件,含
authz-keycloak授权边界与 Kong 对照)、 Keycloak + oauth2-proxy(Nginx Ingress auth-url)、 Traefik ForwardAuth - 入口控制器退役迁移:
IAM 入口迁移:ingress-nginx 退役后的 Keycloak 认证网关落地(
auth-url等认证注解不在ingress2gateway转换范围内,三条替代路线的差异、验证与回滚) - 网格内(东西向)零信任接入:
Istio + Keycloak JWT 认证与 IAM 授权(RequestAuthentication + AuthorizationPolicy,含 istiod 拉取 JWKS 的刷新窗口与
audiences校验边界) - 上游 IdP 联邦(企业身份源接入): Microsoft Entra ID 组声明与 IAM 权限映射(组 overage 静默失效、内置 Microsoft provider 与通用 OIDC provider 的能力边界、多租户 issuer 校验)、 企业微信 / 飞书 / 钉钉 OIDC 统一登录、 LDAP / AD 用户联邦、 Dex + Keycloak 联合身份
- 应用与后端接入: Spring Boot 3/4 资源服务器接入 Keycloak(IAM 角色映射、audience 与 Security 7 的 typ 校验)、 Keycloak Adapter 弃用迁移(服务端 Web 应用)、 客户端认证方式选型与凭据轮换(服务间调用的 secret / private_key_jwt / mTLS)
- 前端框架接入(本文档外,见 Blog):
Next.js + Auth.js 对接 Keycloak 的 IAM 客户端接入(access_token 不自动刷新导致「Session 还在、后端全 401」、并发刷新下同一个
invalid_grant与 BFF 场景含义不同、signOut()不结束 Keycloak SSO 会话) - 自带 OIDC 客户端的应用接入:
Grafana 的角色映射、
Argo CD 的 groups claim 与 Casbin RBAC(confidential/PKCE 路线选择、CLI
--sso回调、policy.default边界)、 Harbor 的组权限与 claim 判定路径(认证模式切换前置约束、userinfo 与 ID token 的取值优先级、CLI secret)、 Jenkins 的 oic-auth 组映射(microprofile-jwt的groups是 realm 角色而非用户组、空数组不回退 ID token、Jenkins 组名逐字符匹配、API token 与 escape hatch)、 MinIO 的 policy claim 与 STS 判定(claim 只从 ID token 读、残留的claim_prefix会改变实际查找的 claim 名、role_policy与claim_name的互斥边界)、 Apache Superset 的组映射与 userinfo 取值(provider 名必须命中 FAB 内置名单、用户与组只从/userinfo读所以勾的是 Add to userinfo、api_base_url缺失或结尾少斜杠导致 404、AUTH_ROLES_SYNC_AT_LOGIN默认关闭使改组不生效) - 凭据系统与人员登录(密钥管理):
OpenBao / Vault OIDC 接入 Keycloak(OIDC 角色与 JWT 角色的边界、回调地址逐字符对齐、issuer 由 discovery URL 主机名推导导致内外网地址不一致时配置阶段失败、
full.path组别名前导斜杠、Token 与会话解耦) - AI Agent / MCP 接入:
Keycloak 作为 MCP 授权服务器(
resource参数与 aud 绑定、26.8.0 的指南口径变更与 CIMD Resource indicator allow list、实验特性resource-indicators的过滤语义、MCP 2026-07-28 的注册/iss/step-up 变更、CIMD 对接 VS Code / Claude Code) - 报错定位(已移入 Blog):
oauth2-proxy 常见错误、
Keycloak 重定向循环与 401、
单点登出不彻底、
身份代理方向登出令牌不验签、
会话超时、
管理员账号进不去、
CORS 与 Web Origins、
Token 体积与 Cookie 膨胀、
--optimized报 build time options 不一致、 域内免登(Kerberos/SPNEGO)不生效、 签名密钥轮换后验签失败(kid / JWKS 缓存) - 安全与合规加固: PAR 授权请求、 金融级 FAPI 2.0 合规(client policy 绑定)、 审计日志与等保、 最小权限落地、 反向代理真实客户端 IP 与信任边界、 X.509 客户端证书登录与 IAM mTLS 落地(证书校验责任分层、认证器默认值、六个代理 lookup provider 与证书链重建)
- 授权模型落地: Keycloak 细粒度权限与授权策略、 Keycloak + OpenFGA 的 ReBAC 集成
- Token 与 claim 链路:
Keycloak 的 aud 从哪来:IAM audience 生成链路与排错(access token 的
aud完全由 protocol mapper 产生、ID token 默认被固定为登录客户端、默认rolesscope 里的 Audience Resolve 为什么必然带出account、evaluate-scopes预览端点与轻量 token 的lightweight.claim前提) - 生产运维: 高可用与灾难恢复、 跨机房多集群双活、 Prometheus 监控、 OpenTelemetry 链路追踪、 运维巡检清单
- 界面与邮件本地化:
Keycloak 中文界面与 IAM 邮件本地化排错(
zh_CN与zh_Hans谁生效、locale 解析优先级、邮件三条消息只翻一半、主题缓存清理与回滚) - 版本升级:
Keycloak 升级与零停机滚动更新(用
kc.sh update-compatibility退出码判定能否滚动、强制停机的特性/缓存/数据库选项、数据库迁移阈值与手工脚本、schema 只能前滚时的回滚路径) - 配置即代码:
IAM 配置即代码:keycloak-config-cli 声明式 Realm 管理与误删防护(state/checksum 判定、
import.managed.*误删防护、无 dry-run 下的预演与回滚) - 扩展开发与交付:
Keycloak 自定义 SPI 扩展的生产交付(
kc.sh build与 provider 注册表的时间线、spi-<spi-id>--<provider-id>--<property>双连字符语义、spec.startOptimized隐含契约、四层验证与回滚顺序) - 服务间(非人类)身份:
SPIFFE/SPIRE 工作负载身份落地(节点认证与工作负载认证两级模型、Selector 静默失败为何是排错第一现场、CSI 挂载 Workload API socket、四层验证与回滚顺序、与 Keycloak 人类 IAM 的分工边界)、
Kafka 接入 Keycloak OAUTHBEARER(broker 与客户端两侧的监听器前缀写法、
org.apache.kafka.sasl.oauthbearer.allowed.urls系统属性默认拒绝、expected.audience/expected.issuer精确匹配与 4.4.0 的启动即校验、principal 取sub(UUID)还是preferred_username、轻量级 access token 下 mapper 需勾lightweight.claim否则aud进不了 token、ACL 与回滚顺序)、 RabbitMQ 接入 Keycloak OAuth 2.0(client scope 的名字就是 vhost 权限、scope_prefix会整体替换前缀、scope_aliases把 Keycloak 角色映射成权限、topic exchange 绑定需要读+写与三段式、管理 UI 要用 public client 且 OAuth 默认关闭 basic auth、token 过期在 AMQP 0.9.1 上不断连只拒绝操作、frame_too_large与initial_frame_max默认 4096) - 数字凭证签发(对外凭证 / 钱包出示):
IAM 数字凭证:Keycloak OID4VCI 签发与撤销边界(
oid4vc-vci的 preview 边界与最小特性集、SD-JWT VC 必须用带证书链的 ES256 密钥、client scope 即一种凭证类型、JWT proof 与持有者绑定、撤销只阻止刷新而非即时作废、错误对照表与回滚顺序)
已覆盖主题:
| 主题 | 关键词 |
|---|---|
| Istio + Keycloak JWT 认证与 IAM 授权落地 | RequestAuthentication, AuthorizationPolicy, requestPrincipals, iss 精确匹配, jwksUri 与 istiod 拉取模式(PILOT_JWT_ENABLE_REMOTE_JWKS), 20 分钟刷新窗口与 fail-closed, audiences 缺失即不校验, iss/aud/kid 三类 401 的区分, outputClaimToHeaders, forwardOriginalToken, ambient waypoint 的 targetRefs |
| Keycloak 社交登录配置:Google / GitHub / Apple / Microsoft | Google OAuth, GitHub OAuth, Apple Sign In, Microsoft Entra ID, JIT Provisioning, 属性映射, 回调 URI 排错 |
| Grafana 接入 Keycloak OIDC:IAM 单点登录与角色映射 | Grafana SSO, generic_oauth, role_attribute_path, JMESPath, realm_access.roles vs groups claim, allowed_groups, role_attribute_strict, validate_id_token, Team Sync 限制 |
| Argo CD 接入 Keycloak OIDC:IAM 单点登录与 RBAC 权限排错 | confidential vs PKCE 两条路线的选择边界、argocd login --sso 的 localhost:8085 回调与 /pkce/verify、invalid_request: Missing parameter: code_challenge_method、Group Membership mapper 的 full.path 默认值与同名层级组取舍、Casbin g/p 语义与组必须先分配角色、policy.default 无法被 deny 拦截、enableUserInfoGroups + userInfoPath 兜底、requestedIDTokenClaims 不替代 mapper、issuer 不匹配报错、rbac can/validate 离线校验与回滚 |
| Keycloak 26.7.4 安全补丁解读与 IAM 升级判断 | 26.7.4, CVE-2026-90997, stateless 模式重放防护, MySQL/MariaDB 行列语义, private_key_jwt, DPoP proof, TOTP, FGAP v2 impersonation, broker 用户名碰撞, SAML DEFLATE 内存泄漏 |
| Keycloak 26.7.3 安全补丁解读与 IAM 升级清单 | 26.7.3, CVE, FGAP v2 管理面越权, 授权码重定向, not-before 吊销, token exchange, DPoP, 升级优先级与回滚 |
| Keycloak 26.7 新特性深度解读 | SCIM API, 多集群 HA, AuthZEN, OpenID SSF, SAML Step-up, Identity Brokering API V2 |
| Keycloak 审计日志配置与 IAM 合规实践 | 登录审计、管理员事件、Syslog/ELK 导出、等保 2.0 对齐、事件数据库维护 |
| Keycloak + oauth2-proxy 集成指南 | OIDC, audience, CSRF, redirect loop, Nginx Ingress, ForwardAuth |
| oauth2-proxy 深度介绍 | 架构原理、Provider 选型、Cookie/Session、安全加固、与 Pomerium/Traefik/Nginx 对比 |
| IAM 目录对接:Keycloak LDAP / AD 用户联邦 | LDAPS 连接、用户搜索与同步策略、属性映射、组导入、AD 与 OpenLDAP 差异、常见错误排错 |
| Keycloak Adapter 弃用迁移指南 | 从 Keycloak Adapter 迁移到标准 OIDC 库(Spring Security、openid-client、authlib),逐语言迁移路径、角色映射、Token Refresh、常见踩坑与回滚 |
| Keycloak Prometheus 监控指标详解 | metrics 端点启用、ServiceMonitor 采集、Grafana Dashboard 21997、关键告警规则与常见排错 |
| Keycloak 生产巡检与运维清单 | 日常健康检查、监控告警阈值、证书管理、IAM 运维应急响应、月度审计与性能基线 |
| Keycloak 高可用集群部署与灾难恢复 | 多节点集群、JGroups 发现、InfiniSpan 缓存一致性、数据库备份恢复流程与故障演练 |
| Keycloak 细粒度权限与授权策略实战 | Groups vs Roles、Composite Roles、Authorization Services、Policy Evaluation、资源级权限控制 |
| Traefik ForwardAuth + Keycloak + oauth2-proxy | Traefik ForwardAuth 中间件、Middleware CRD、IngressRoute TLS、多中间件链式调用、与 Nginx auth-url 对比 |
| Dex + Keycloak 联合身份:Kubernetes 集群 OIDC 认证 | Keycloak 上游 OIDC 源、Dex OIDC connector、Kubernetes API Server 集成、groups claim 传递、kubelogin、RBAC 绑定 |
| Keycloak 集成企业微信 / 飞书 / 钉钉 OIDC 统一登录 | 企业微信 OAuth、飞书 OIDC、钉钉 OIDC、Identity Provider Broker、回调地址配置、属性映射与 JIT Provisioning |
| Keycloak 生产数据库配置 — PostgreSQL 实战 | H2 迁移 PostgreSQL、Kubernetes Secret 凭据管理、连接池调优、Liquibase 自动建表、常见数据库错误排错 |
| Keycloak 直连 K8s OIDC — API Server 认证与 RBAC | kube-apiserver OIDC 参数、groups claim 映射、kubelogin 接入、RBAC 绑定、与 Dex 方案对比 |
| Keycloak SMTP 邮件配置与密码重置 | SMTP 配置(Gmail/企业微信/AWS SES)、忘记密码流程、邮箱验证、网络层排错、生产检查清单 |
| Keycloak 集群缓存调优与排错指南 | InfiniSpan 分布式缓存、JGroups 发现、缓存穿透、会话亲和性、集群脑裂诊断 |
| Keycloak Redis 外部会话缓存配置 | Redis 外部 Session 缓存、跨节点 Session 共享、Infinispan vs Redis 选型、Kubernetes 部署与排错 |
| Supabase Auth 与 Keycloak 对比及集成 | Supabase GoTrue、Row Level Security、Keycloak 作为外部 OIDC 源、JWT 自定义 Claims、社交登录互通 |
| Dex 身份联邦指南:从原理到 K8s 集成 | Dex OIDC Connector、Kubernetes OIDC 认证、多上游 IDP 联邦、groups claim 映射 |
| IAM 最小权限原则落地指南 | Least Privilege、权限反模式、JIT 提权、角色粒度分层、Keycloak 权限审计、等保最小权限要求 |
| Keycloak 条件认证与 Step-Up 实战 | Authentication Flow、条件 OTP、角色分级 MFA、IP 位置条件、Step-Up 二次认证、LoA 认证级别 |
| Passkey / WebAuthn / FIDO2 IAM 企业落地指南 | FIDO2 注册认证 Mermaid 流程图解、Keycloak Passkey 配置、Conditional UI 自动填充、CTAP 认证器管理、企业恢复策略与常见踩坑 |
| IAM SCIM 用户自动配置实战 | IAM 自动化供应、Joiner-Mover-Leaver、HR→IDP→应用全链路同步、Keycloak SCIM 插件、Azure AD SCIM、常见排错 |
| Keycloak 原生 SCIM API 实战:IAM 入站用户配置与能力边界 | scim-api 特性与 realm 双开关、服务账号 audience 校验、ServiceProviderConfig 能力边界(bulk/etag/排序/改密不支持)、管理员资源保护 403、401/403/404 排错与回滚 |
| Keycloak 生产环境完整部署路线图 | 从零到高可用全景路线:部署方式选型、数据库、反向代理、集群、监控、备份、安全加固、运维巡检八步走 |
| IAM 多协议集成实战:OAuth 2.0、OIDC、SAML 在统一身份平台中的协同 | IAM 多协议架构、OIDC+SAML 共存、sub/NameID 统一、跨协议 SSO 会话、SAML 证书轮换、协议桥接排错 |
| OAuth 2.0 设备授权流程(Device Authorization Grant)IAM 实战 | RFC 8628、CLI 工具 SSO 登录、Device Code Flow 原理与 Mermaid 时序图、Keycloak Device Flow 配置、Public Client 安全考量 |
| OAuth 2.0 Token Introspection 实践 - API 网关验证 Token 的正确方式 | RFC 7662、API 网关验证 Token、Nginx auth_request 集成、Kong/APISIX 方案、Introspection 缓存策略、vs JWT 本地验证、Keycloak 配置 |
| IAM 密码策略实战 - NIST SP 800-63B 与等保 2.0 在 Keycloak 中的落地 | NIST SP 800-63B、等保 2.0 密码要求、Argon2id 哈希切换、泄露密码黑名单、分层密码策略、密码策略排错 |
| AD FS 迁移 Microsoft Entra ID:IAM 联邦退场实战 | 域联邦转托管、staged rollout 边界、60 分钟转换窗口、NameID 受限声明集、SAML 150 组上限、回滚命令、故障对照表 |
| Keycloak User Profile 用正则限制企业邮箱注册 | User Profile pattern validator、邮箱后缀白名单、正则边界、验证方法、可绕开场景 |
| Keycloak Organizations 多租户实践:B2B 身份隔离与成员生命周期 | Organizations 启用、managed/unmanaged 成员、邀请与 Admin REST API、organization claim 映射、组织组、存量 Realm 认证流迁移、排错表 |
| Keycloak Token Exchange 实战:Standard V2 配置与 V1 迁移 | Standard V2 vs Legacy V1、客户端开关、audience 只能收窄、Requested audience not available、Client is not within the token audience、报错原文对照、DPoP/mTLS 令牌换手限制、撤销链、downscope-assertion-grant-enforcer、FGAP 迁移 |
| Pomerium Core 代理认证实战:Keycloak + JWT 验签保护内部应用 | 开源版代理认证、/oauth2/callback、claim/groups 替代 groups、X-Pomerium-Jwt-Assertion 验签、JWKS、aud/exp 校验、排错与回滚 |
| Envoy Gateway 原生 OIDC + Keycloak 落地与排错 | Gateway API、SecurityPolicy.oidc、redirectURL 与路由匹配约束、并发授权流导致 pkce_verification_failed、cookieDomain、AES-GCM 会话升级与强制重登 |
| IAM BFF 模式与 SPA Token 安全:架构选择与并发刷新排错 | RFC 10017 三种浏览器端架构(BFF / Token-Mediating Backend / 浏览器 OAuth 客户端)、Session Cookie 与 CSRF 硬性要求、Keycloak 刷新轮换的 reuse_id 语义、并发刷新 invalid_grant 排错、单飞刷新实现与回滚 |
| Keycloak Hostname v2 配置与 v1 选项迁移 | hostname v1 移除清单、v1→v2 选项映射、backchannel 行为反转、四种拓扑最小配置、Operator CR 字段、启动校验错误文本、issuer/邮件链接排错与回滚 |
| Keycloak PAR 实战:IAM 授权请求参数不再走浏览器 URL | RFC 9126、require.pushed.authorization.requests vs fapi-2 secure-par-content、request_uri 60 秒有效期与消费时机、Pushed Authorization Request is only allowed. 排错、oauth2-proxy / Dex / kube-apiserver 支持现状、回滚 |
| Keycloak FAPI 2.0:Client Policy 绑定与破坏性影响 | FAPI 1.0 / CIBA / 2.0 六个全局 profile 的选用边界、四个 fapi-2-* profile 的 executor 级差异(mTLS vs DPoP)、全局 profile 不自动生效与 PUT 整体替换语义、Any Client 锁死 Admin Console、consentRequired / fullScopeAllowed / useDpop 被自动改写且不随策略回滚、assertion aud 只认 realm issuer(invalid audience in client assertion)、client_secret_* 被拒、EdDSA 不在算法白名单、存量审计清单与回滚顺序 |
| APISIX 接入 Keycloak:IAM 网关认证与授权排错 | openid-connect 与 authz-keycloak 的职责边界、redirect_uri 子路径约束、X-ID-Token 是 base64 claims 而非 JWT、session.secret 与 ssl_verify 的版本差异、session_contents 的反向回填、滚动发布掉线、Kong OSS 无官方 OIDC 插件 |
| Keycloak 反向代理真实客户端 IP 与代理信任边界 | proxy-headers / proxy-trusted-addresses 默认行为、passthrough 与 PROXY protocol 互斥、$proxy_add_x_forwarded_for 追加语义、ingress-nginx use-forwarded-headers 语义、请求头清洗清单、伪造头验证与回滚顺序 |
| Keycloak X.509 客户端证书登录:IAM mTLS 认证与代理证书链转发排错 | PKIX 校验责任分层(容器 / 代理 / revalidate-certificate-enabled)、https-client-auth 与信任库全局共享、K8s 集群 CA 回落到系统信任库的越权风险、认证器十余个选项的源码默认值、10 种身份来源与默认正则 (.*?)(?:$) 陷阱、Bypass identity confirmation 免密、nginx/haproxy/traefik/envoy/apache/rfc9440 六个 lookup provider 的头名与 certificate-chain-length 默认 1、证书链重建、症状与日志原文对照、分层回滚 |
| Keycloak + OpenFGA:IAM 细粒度授权 ReBAC 落地 | Audience mapper 字段与默认值、authn.oidc.* 必填项、仅 RS256 的源码级约束、sub vs preferred_username 作为权限主体、Write API 非幂等、CVE-2026-55689 排查与回滚 |
| Keycloak OpenTelemetry 追踪接入与 IAM 采样成本控制 | tracing-enabled / tracing-jdbc-enabled / tracing-sampler-type 的 build time 源码依据、--optimized 下配置值不一致直接启动失败、默认采样率 1.0 与 JDBC span 成本、日志 traceId 与 sampled 标志、信号专属 OTLP 端点不补 /v1/traces、Operator CR 与回滚 |
| Keycloak 客户端认证与 IAM 凭据轮换:client secret、private_key_jwt、mTLS | 四种 Client Authenticator 的算法硬边界(Algorithm is not asymmetric / is not symmetric)、断言 iss=sub、aud 五个允许值、Max expiration 60 秒与 iat 判定、jti 单次使用、Preview 特性 client-secret-rotation 的双 secret 窗口、x509cert-lookup provider 与 trust-proxy-verification 前提 |
| Keycloak 作为 MCP 授权服务器:IAM audience 绑定与 resource indicators 落地 | MCP 授权规范的 resource MUST 与 Keycloak 26.7.4→26.8.0 的指南口径变更(Not supported → Experimental)、两条落地路径(scope + Audience mapper / 实验特性 resource-indicators)、CIMD executor 新增的 Resource indicator allow list、aud 是过滤而非追加(invalid_target 两类文案)、ResourceIndicatorValidation 校验规则实测表(含无路径放行、scheme 不限制、URN 拒绝 /、urn:client: 前缀大小写敏感)、refresh token 里的 resource 一致性、MCP 2026-07-28 的注册优先级/iss/step-up 变更、CIMD 对接 VS Code / Claude Code 的 executor 与 policy 边界、回滚顺序 |
| Keycloak 自定义 SPI 扩展的生产交付:镜像构建、Operator 部署与回滚 | providers 目录 JAR 必须经 kc.sh build 才进 provider 注册表、单连字符 spi-* 选项导致 reaugmentation 不检测、Docker 改写 mtime 导致 start --optimized 拒绝启动与 touch -m --date=@<epoch> 修法、spec.image 与 spec.startOptimized「假定镜像已 augmented」的隐含契约、/admin/serverinfo 与 /authentication/authenticator-providers 分层验证、卸载即「删 JAR + 重新 build」与回滚顺序 |
| IAM 配置即代码:keycloak-config-cli 声明式 Realm 管理与误删防护 | realm attributes 中的 de.adorsys.keycloak.config.state-{0}-{1} 与 .import-checksum-{0}、checksum 比对的是文件而非 Keycloak 状态(不检测漂移)、19 个 import.managed.* 的出厂默认值与 client-scope/scope-mapping 被 properties 覆盖为 no-delete 的文档/实现落差、用户联邦删除重建连带删用户与 offline token、import.remote-state.enabled=false 的危险语义、硬编码 encryption-salt、skip-server-info 与 availability check 前置条件、v6.5.1 CI 矩阵最高 26.5.5 而 Keycloak 稳定版 26.7.4、无 dry-run 与 FGAP v2 边界、预演与回滚顺序 |
| SPIFFE/SPIRE 工作负载身份 IAM 落地 | SPIFFE ID 与 trust domain 划分、X509-SVID 恰好一个 URI SAN(授权必须在链校验之后再做 ID 校验,否则同域内任意服务可互相冒充)、JWT-SVID 的 sub/aud 语义、节点认证(k8s_psat + TokenReview)与工作负载认证的两级模型、registration entry = SPIFFE ID + selector(AND) + parent ID、selector 不匹配是静默失败、节点别名 entry 避免绑定 node UID、ClusterSPIFFEID 声明式注册 vs spire-server entry create、默认 TTL(X509 1h / JWT 5m / CA 24h)与 entry 级覆盖、CSI 内联卷 csi.spiffe.io 挂载 Workload API socket 与驱动自身仍需 hostPath 的限制、四层验证命令、驱动异常时 Pod 卡在 Terminating 的行为、与 Keycloak 人类 IAM 的四点边界(含「JWT-SVID 不能当 client assertion 用」)、注册面→应用面→基础设施面的回滚顺序与 CRD/PVC 清理 |
| IAM 入口迁移:ingress-nginx 退役后的 Keycloak 认证网关落地 | ingress-nginx 2026-03 退役、最后版本 controller-v1.15.1 与仓库归档事实、ingress2gateway 支持 ingress-nginx 30+ 注解但认证注解一条都不转换、三条替代路线(Traefik kubernetesIngressNGINX 注解兼容 provider 的 ForwardAuth 行为差异与 rewrite-target 下 X-Forwarded-Uri 取重写后路径、auth-signin 自动追加 rd 的开放重定向边界;Gateway API + extAuth 的 path 追加语义与 pathOverride、headersToBackend;网关原生 OIDC 下 claimToHeaders 不支持数组 claim)、未认证 401→登录页缺口、五条切换验证命令、错误对照表、按 host 切流与回滚 |
| Keycloak Kerberos/SPNEGO 对接 AD 域:IAM 内网免登配置与排错 | SPNEGO 完整链路(401 + WWW-Authenticate: Negotiate → 浏览器取 ST → Keycloak 用 keytab 接受票据)、Alternative 与 Required 在无 SPNEGO 能力浏览器上的行为差异、AD 侧 setspn + ktpass(/princ 大小写敏感、/crypto 必填、同一账号不能映射多个服务实例)、容器镜像不含 /etc/krb5.conf 的官方处理方式、Keycloak 不走 KRB5_KTNAME 而用 provider 的 keyTab/serverPrincipal 建 JAAS 登录、LDAP 联邦与 Kerberos provider 的属性差异、krbPrincipalAttribute 留空 vs 填 userPrincipalName 的映射规则、KERBEROS 特性受 JDK GSS 探测影响的静默失效、Edge/Chrome AuthServerAllowlist 与 NTLM 回落的边界、RFC 4120 错误码对照表、分层回滚顺序 |
| Keycloak –optimized 启动失败:IAM 构建期选项与运行期选项的边界 | build-time / runtime 选项分界(db vs db-url、metrics-enabled vs db-pool-*)、start 的 auto-build 与 --optimized 的硬校验、报错原文与 PropertyException 源码位置、25.x 静默忽略 → 26.0 硬失败 → 26.2 quarkus.properties 误判的版本差异、SPI 键 -enabled / -provider 弱校验、Operator additionalOptions 与镜像的职责划分、provider 时间戳跨环境失败、show-config 诊断与回滚顺序 |
| Keycloak 身份代理登出验签:CVE-2026-18569 与 26.8 升级准备 | 上游 OIDC IdP 的 backchannel logout 令牌校验链路(LogoutEndpoint.backchannelLogout() → TokenManager.verifyLogoutToken() → validateLogoutTokenAgainstIdpProvider())、verify() 早退为何连带放过登出令牌、LogoutTokenValidationCode 八条错误文本与日志细分文本、候选 IdP 按 iss 匹配、alias.sub/alias.sid 与会话/离线会话撤销范围、受影响配置盘点命令、Validate Signatures 加固与 JWKS 可达性前置条件、26.8 强制验签的升级预演与回滚 |
| Keycloak 作为 SAML IdP 接入应用:IAM 端点解析、NameID 与签名排错 | SAML 客户端的 Client ID 必须逐字符等于 SP 发来的 Issuer(查不到即 Client not found.),同一 clientId 复用 OIDC 客户端会得到 Wrong client protocol.;SP 发起时断言投递地址的回退链(AuthnRequest 的 ACS URL → 按 binding 取 Fine Grain 的 ACS → Master SAML Processing URL → Invalid redirect uri)与 IdP 发起时的另一条顺序(ACS POST → management URL → ACS Redirect);NameID 取值规则(persistent 存在用户属性 saml.persistent.name.id.for.<clientId> 里,改 Client ID 等于换一套 NameID;email 格式在用户无邮箱时返回空值);断言 <Conditions> 未配 Assertion Lifespan 时回退到 Realm 的 Access Code Lifespan(默认 60 秒)而 SessionNotOnOrAfter 恒为 SSO Session Max;Sign Documents / Sign Assertions 是两个独立开关、ADFS 需要 CERT_SUBJECT、SHA1 在 Java 17+ 无法验签、Force POST Binding 与 IdP-Initiated SSO URL name;错误对照表与回滚顺序 |
| Keycloak 升级与零停机滚动更新:IAM 升级判定、数据库迁移与回滚 | 26.6.0 起补丁版本支持零停机滚动;kc.sh update-compatibility metadata / check 与退出码 0/1/2/3/4(4 = rolling-updates 特性未启用)、两次命令的配置项必须完全一致否则结论错误、只依赖退出码不解析元数据结构;强制 recreate 的特性(multi-site:v1 / persistent-user-sessions:v1 / stateless:v1)与 --cache* / --db* 选项清单、变更切分原则(换库换缓存不与升版本合并);Operator 默认 RecreateOnImageChange 即停机、Auto / Explicit 取舍、CR 条件 RecreateUpdateUsed;迁移默认超时 30 分钟与 --transaction-setup-timeout、index-creation-threshold 默认 300000 与非阻塞建索引支持的数据库、手工 migration-strategy=manual 与 DATABASECHANGELOG / DATABASECHANGELOGLOCK 预建;schema 只能前滚与「备份恢复才是回滚」、persistent-user-sessions 关闭时非离线会话全丢 |
| IAM 签名密钥轮换排错:Keycloak 的 kid、JWKS 缓存与切换顺序 | Active / Enabled 两个开关与 provider 优先级(“A key pair can have the status Active, but still not be selected as the currently active key pair”)、JWKS 生成只过滤 status.isEnabled() && publicKey != null(被动密钥公钥照发、禁用后立即消失)、GET /admin/realms/{realm}/keys 的 active/status/providerPriority/validTo、验签方 JWKS 缓存默认值(Spring Security 5 分钟、Envoy cache_duration 10 分钟且不因 kid 未命中重取、nginx auth_jwt_key_cache 默认 0、go-oidc 按 kid 重取并报 failed to verify id token signature、PyJWT lifespan 300 秒 + cooldown_duration 30 秒)、先发布公钥 → 再切换签名 → 最后下线公钥的三段式顺序与等待时间取最大值、误禁用旧密钥的一键恢复、not-before 推送不可回滚 |
| Harbor 接入 Keycloak OIDC:IAM 单点登录与组权限映射排错 | 认证模式切换前置约束(库中除 admin 外有本地用户即不可切)、OIDC 模式下不支持本地建号/改密与 /account/sign-in 兜底登录、/c/oidc/callback 源码常量、Keycloak invalid_scope(Invalid scopes: groups)与 scope 逐项校验机制、groups 在 userinfo 与 ID token 之间的取值优先级(userinfo 优先、ID token 兜底)、Group Claim Name 留空时源码不打日志、Group Filter 非锚定正则与非法正则不过滤、OIDC Admin Group 逐字符比较且判定在 Filter 之前、组记录由成员首次登录时的 Populate 落库、CLI secret 与 refresh token、issuer 不匹配报错原文、验证顺序与回滚 |
| Keycloak 跨机房多集群高可用与 IAM 双活部署 | 三种 HA 架构分工(单集群 / multi-cluster v1 / v2)、stateless 特性与外部 Infinispan 退役、同步复制数据库与 commit 延迟 < 10 ms 硬要求、NTP 时钟偏差 > 10 s 导致缓存失效消息丢失、/lb-check 站点探活与 /health/ready 节点探活的分工、数据库 outbox 缓存失效与 realm 写入额外约 100 ms 等待、从 v1 迁移会丢/不丢哪些数据、优化镜像的 build-time 特性坑、回滚边界 |
| Keycloak 联邦 Microsoft Entra ID:组声明与 IAM 权限映射排错 | Entra groups claim 的三种形态(正常 / overage _claim_names + _claim_sources 指向 Graph / hasgroups)、Keycloak 不跟随 _claim_sources 导致静默零组、内置 Microsoft provider 无 openid scope 与 profile 取自 Graph /me、oidc-advanced-group-idp-mapper 的 COMPATIBLE_PROVIDERS 不含 microsoft、tenantId 留空 = common 不限租户、多租户 issuer 模板 {tenantid} 与逗号分隔列表、GUID 匹配与组路径不存在只留一行 warn、claim 查找顺序 access token → ID token → userinfo、FORCE 同步模式会把用户移出组、AADSTS50105 与 emit_as_roles 互斥 |
| Keycloak 中文界面与邮件本地化排错:IAM 界面语言不生效的排查路径 | 本地化三层机制(主题 message bundle / realm overrides / 用户 locale)、internationalizationEnabled=false 时直接返回英文,LocaleSelectorProvider resolveLocale 早退、locale 解析优先级(用户选择 → 用户档案 → 客户端 ui_locales → KEYCLOAK_LOCALE cookie → Accept-Language → realm 默认 → 英文)与 kc_locale 强制切换、官方无 messages_zh_CN.properties 且 zh_Hans 条目优先于 zh_CN(doesLocaleMatch 只比语言 + 国家、不比 script)、登录包 500 vs 487 缺 13 个 key(集中在 credentialOffer* / did / Organization 类,而 webauthn-error-* 已翻译)、邮件 Subject/Body/BodyHtml 三条消息缺一回退英文、语言下拉的双条件 internationalizationEnabled && locale.supported?size gt 1、Effective message bundles 与 Test connection 快速验证、主题缓存清理与回滚顺序 |
| Keycloak 26.8.0 升级:IAM 破坏性变更与检查清单 | 官方 6 条破坏性变更 / 34 条行为变更 / 14 条弃用的影响面分组、IdP mapper 默认不再授予管理角色(CVE-2026-12388,allowAdminRoleMapping 对存量 IdP 同样默认 false、静默失效与既有授权不回收)、X.509 用户认证强制 CA Subject DN 且 Revalidate Client Certificate 弃用、禁用客户端退出 aud/resource_access(CVE-2026-93999)、view-clients 不再返回 client secret、introspection act.sub 改用用户 ID、组策略裸组名只匹配顶层组(CVE-2026-19608)、Authorization Services URI 归一化、Full Scope Allowed 弃用与 full-scope-disabled executor(Any Client 锁死 Admin Console 的排除做法、不追溯存量)、stateless 转正但默认关闭、multi-site/clusterless 退场、登录失败入库、Organization ↔ IdP 多对多迁移、离线会话索引阈值 300000、CVE-2026-18569 未进 26.8.0 的核对结论 |
| GitLab 接入 Keycloak OIDC:IAM 单点登录与 required_groups 静默失效 | client_options.gitlab 的嵌套位置(写到 args 顶层不报错也不写日志)、SAML 与 OIDC 同名键位置不同、required_groups / external_groups / admin_groups / auditor_groups 的 Premium·Ultimate 门禁(Free/CE 上静默不生效)、OIDC 不同步 GitLab 组成员(官方明确声明,组同步需 Group SAML / SCIM)、full.path 前导斜杠与逐字符匹配、scope 写 groups 触发 Invalid scopes: groups、uid_field 静默回退 sub 导致账号分裂、client_auth_method 三种受支持值与其余值走请求体、Git over HTTP 不能用 SSO 密码、负测试验证法与回滚 |
| MinIO 接入 Keycloak OIDC:IAM 策略映射与 SSO 排错 | MinIO 只认 claim_name 指定的单个 claim(默认 policy),不读 groups / realm_access.roles;claim 仅从 ID token 读取,claim_userinfo 只补缺不覆盖且要求 access token;GetIAMPolicyClaimName 实际查找名是 claim_prefix + claim_name(claim_prefix 已标废弃但拼接逻辑仍在,残留旧值会让报错里出现带前缀的 claim 名);role_policy 与非默认 claim_name 互斥,而 claim_name 保持默认值时不触发该冲突校验;claim 值接受字符串 / 逗号分隔 / 字符串数组三种格式,数组里的非字符串元素被静默跳过;claim 缺失与策略不存在对应两条不同的 STS 报错原文;无效 RoleArn 在存在 claim 型提供方时静默降级(为 AWS SDK 的 dummy ARN 留口);单实例只允许一个 claim 型提供方;scopes 是替换而非追加发现文档的 scope 列表;redirect_uri_dynamic 默认 off 与 LB 轮询下的 Invalid parameter: redirect_uri;vendor=keycloak + keycloak_admin_url 的用户有效性校验与 keycloak_realm 留空默认 master;STS exp 与 DurationSeconds 的覆盖语义;回滚顺序 |
| OpenSearch Dashboards 接入 Keycloak OIDC:IAM 单点登录与 roles claim 取不到的排错 | 两个组件两套配置(OpenSearch Security 插件 openid_auth_domain vs Dashboards opensearch_security.openid.*)、浏览器 SSO 路径携带的是 ID token(源码 Bearer ${idToken})而 Keycloak 内置 roles scope 的 realm roles mapper 默认只写 access token、嵌套 claim 必须写成 YAML 列表(点号写法只报同一句 warn)、roles_key 值只是 backend_roles 还需映射到 OpenSearch 角色、plugins.security.* 前缀在 Dashboards 上直接 FATAL、cache_jwks_endpoint 在 OIDC 域默认 false、回调路径 /auth/openid/login 与 base_redirect_url、时钟偏移、回滚顺序 |
| OpenBao / Vault OIDC 接入 Keycloak:IAM 运维登录与 issuer 排错 | OIDC 角色与 JWT 角色的边界(三个验签来源互斥、bound_audiences 在 Vault 1.17 起对带 aud 的 token 强制精确匹配、expiration_leeway 默认 150 秒)、UI / CLI / form_post 三条回调地址逐字符对齐(含 mount 路径出现在 URL 里)、期望 issuer 由 discovery URL 主机名推导导致内网地址访问 + 前端域名 issuer 时配置阶段失败(附日志原文、bound_issuer 无法绕过、三种修法与验证命令)、groups_claim → Identity 组别名与 full.path 默认 true 的前导斜杠、Audience mapper 的 included.client.audience 与默认开关、Keycloak 拒绝未定义 scope、callbackmode=direct 确认页与设备流、verbose_oidc_logging 的敏感边界、Token 与 IdP 会话解耦、报错对照表与回滚顺序 |
| Kafka 接入 Keycloak OAUTHBEARER:IAM 服务账号认证与 ACL 授权 | SASL/OAUTHBEARER, listener.name.<listener>.oauthbearer.sasl.server.callback.handler.class, listener.name.<listener>.oauthbearer.sasl.oauthbearer.jwks.endpoint.url 的双段前缀、org.apache.kafka.sasl.oauthbearer.allowed.urls 系统属性(4.0.0 起默认空 = 默认拒绝、字符串精确匹配、客户端与 broker 两侧各生效一次、报错原文)、sasl.oauthbearer.expected.audience / expected.issuer 精确匹配与 4.4.0 起「配了 JWKS 就必须给」、allow.unverified.* 是关闭校验而非通配、Keycloak oidc-audience-mapper 默认只写 access token 且 Audience Resolve 跳过自身、服务账号 token 的 sub 是 UUID 而 preferred_username 是 service-account-<client-id>、sasl.oauthbearer.header.urlencode(RFC 6749 §2.3.1)、4.x 抹平 secured 子包导致的 ClassNotFoundException、principal → ACL、错误对照表与回滚顺序 |
| RabbitMQ 接入 Keycloak OAuth 2.0:IAM 权限映射与排错 | rabbitmq_auth_backend_oauth2、client scope 名即 RabbitMQ scope(rabbitmq.read:*/* / rabbitmq.tag:management,拼错不报错只静默无效)、include.in.token.scope 与 Default vs Optional 的取舍、aud 必须包含 resource_server_id 而值由 included.custom.audience 提供、管理 UI 用 public client 与后端 confidential client 的分工、management.oauth_scopes 缺 tag scope 导致 Not authorized、management.oauth_enabled 默认关闭 basic auth 使 IdP 故障时管理入口一起消失、scope_prefix 是整体替换而非追加、scope-to-permission 三段式 <permission>:<vhost>/<name>[/<routingkey>]、topic exchange 绑定需 read+write 的 */*/*、通配符特殊字符需 URL 编码、{user_name} / {sub} 变量展开、scope_aliases 与 additional_scopes_key 两条角色映射路线、{bad_cert,hostname_check_failed} 与 hostname_verification 的两处文档口径差异、frame_too_large 与 initial_frame_max 默认 4096、AMQP 0.9.1 与 1.0 在 token 过期上的行为差异、Operator 的 additionalPlugins / additionalConfig、错误对照表与分层回滚 |
| IAM 数字凭证:Keycloak OID4VCI 签发与撤销边界 | OID4VCI 1.0 Final(2025-09-16)、Keycloak 26.8.0 preview 与 oid4vc-vci 最小特性集(不要用 --features=preview)、HAIP 证书链要求(叶证书不可自签、trust anchor 不进 x5c、生成型 realm key 不能签 SD-JWT VC)、client scope 即一种凭证类型与两个开关的分工、realm 属性默认值(vc.c-nonce-lifetime-seconds 60 / credentialOfferLifespanS 300 / refresh interval 604800 ≤ lifetime)、JWT proof 字段硬要求(typ/aud/nonce/iat ±30s/jwk 三选一)、cnf 与 _sd_hash 持有者绑定、无状态列表 → 撤销只阻止刷新、生效时间 ≈ refresh interval、refresh token 与登出解耦且最长 1 年、OID4VCI access token 的 aud 用途锁定、按 client 批量撤销缺失、unknown_credential_identifier 等错误对照与回滚顺序 |
| Keycloak 的 aud 从哪来:IAM audience 生成链路与排错 | access token 的 aud 完全由 protocol mapper 产生(initToken() 只写 azp)而 ID token 默认被服务端固定为登录客户端(idToken.audience(client.getClientId()),mapper 只能用 addAudience 追加)、roles 这个默认 client scope 里装着 realm roles / client roles / audience resolve、aud 里必然出现 account 的完整推导(AccountRoles.DEFAULT = view-profile / manage-account 被加成 realm 默认角色的复合角色 → Audience Resolve 命中所有「用户持有 client 角色的 client」)、oidc-audience-mapper 的 id.token.claim 默认 false 与客户端被禁用/删除时的静默跳过、userinfo.token.claim 缺省跟随 id.token.claim 与 introspection.token.claim 缺省跟随 access.token.claim 两条向后兼容规则、轻量 access token 下只读 lightweight.claim 不回退 access.token.claim、evaluate-scopes/generate-example-{access-token,id-token,userinfo} 三个预览端点、内置 roles/web-origins/acr/basic 的 Include in token scope 为 false、错误对照表与按 scope 粒度评估的影响面和回滚顺序 |