<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Iam on IDaaS Book</title><link>https://idaas.xlabs.club/tags/iam/</link><description>Recent content in Iam on IDaaS Book</description><generator>Hugo</generator><language>zh-CN</language><copyright>Copyright (c) 2020-2024 xlabs.club</copyright><lastBuildDate>Fri, 25 Sep 2026 23:10:06 +0800</lastBuildDate><atom:link href="https://idaas.xlabs.club/tags/iam/index.xml" rel="self" type="application/rss+xml"/><item><title>Keycloak 作为 MCP 授权服务器：IAM audience 绑定与 resource indicators 落地 | IDaaS Book</title><link>https://idaas.xlabs.club/docs/solution-blogs/keycloak-mcp-authorization-server/</link><pubDate>Mon, 21 Sep 2026 23:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/docs/solution-blogs/keycloak-mcp-authorization-server/</guid><description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;&#10;&lt;p&gt;MCP server 用 Keycloak 做授权服务器之后，接入方报的错几乎都是同一个：token 能签发、能验签、&lt;code&gt;iss&lt;/code&gt; 也对，但 MCP server 返回 &lt;code&gt;401 invalid_token&lt;/code&gt;，描述是「token 的 audience 不是给我的」。原因在 MCP 授权规范的一条 MUST——客户端必须在&lt;strong&gt;授权请求和 token 请求&lt;/strong&gt;里带 &lt;code&gt;resource&lt;/code&gt; 参数（&#13;&#10;&#13;&#10;&lt;a class="link link--text" href="https://datatracker.ietf.org/doc/html/rfc8707" rel="external"&gt;RFC 8707&lt;/a&gt;），MCP server 必须校验 token 是专门为它签发的；而 Keycloak 的官方文档在 26.7.4 明确写着「Keycloak cannot recognize &lt;code&gt;resource&lt;/code&gt; parameter」，MCP 2025-06-18 / 2025-11-25 / 2026-07-28 三个版本都被标为 &lt;em&gt;Partially Supported without Resource Indicators&lt;/em&gt;。&lt;/p&gt;&#10;&lt;p&gt;也就是说：客户端一定会带 &lt;code&gt;resource&lt;/code&gt;，Keycloak 默认&lt;strong&gt;静默忽略&lt;/strong&gt;它，既不报错也不按它设置 &lt;code&gt;aud&lt;/code&gt;。这一篇文章讲清两件事——怎么在官方推荐路径下把 &lt;code&gt;aud&lt;/code&gt; 绑对，以及 26.6.0 起已进入发布版、但仍属实验特性的 resource indicators，在源码层面到底做了什么、什么情况下会把已经能跑的客户端打断。&lt;/p&gt;&#10;&lt;p&gt;结论先说：&lt;strong&gt;Keycloak 的实验实现是「过滤」aud，不是「添加」aud。&lt;/strong&gt; 如果 token 里本来没有目标资源的标识，&lt;code&gt;resource&lt;/code&gt; 不会帮你补上，而是直接返回 &lt;code&gt;invalid_target&lt;/code&gt;。理解这一点，能省掉一轮线上排错。&lt;/p&gt;&#10;&lt;h2 id="适用与不适用"&gt;适用与不适用&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;场景&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;是否适用&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;说明&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;MCP server 放在 Keycloak 后面，客户端是 VS Code / Claude Code / MCP Inspector&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✅&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;需要 CIMD（&lt;code&gt;client_id&lt;/code&gt; 是 URL）或 DCR 注册客户端&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;一个 realm 里有多台 MCP server，同一个 agent 客户端要分别取 token&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✅&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;aud 收敛为单值是这套机制的核心价值，跨 server 重放会被拒&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;只需要给单台 server 发 token，且不想开实验特性&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✅（走官方 scope 路径）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;见下节路径 A，稳定、无需实验特性&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;MCP 2025-03-26 及更早版本&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;❌&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;该版本不要求 &lt;code&gt;resource&lt;/code&gt; 与 aud 绑定，Keycloak 文档写明 &lt;em&gt;No special setup is required&lt;/em&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;本地 stdio 传输的 MCP server&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;❌&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;没有 HTTP 授权层，与本文无关&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;生产环境无法接受「实验特性可能破坏性变更」&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;⚠️&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;路径 A 即可满足 MCP 的 MUST/SHOULD 集合，路径 B 是增益不是前提&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="两条落地路径"&gt;两条落地路径&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;路径 A：scope 驱动（官方文档路径）&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;路径 B：resource 驱动（实验特性）&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;机制&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;用 &lt;code&gt;scope&lt;/code&gt; 触发 Audience mapper，把 MCP server 的标识&lt;strong&gt;追加&lt;/strong&gt;进 &lt;code&gt;aud&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;解析 &lt;code&gt;resource&lt;/code&gt; 参数，把 &lt;code&gt;aud&lt;/code&gt; &lt;strong&gt;替换&lt;/strong&gt;成该参数对应的资源&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;前置配置&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;client scope + Audience mapper&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;在 A 的基础上，额外给 MCP server 的客户端配 &lt;code&gt;resource_url&lt;/code&gt; 属性，并启用 &lt;code&gt;resource-indicators&lt;/code&gt; 特性&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;特性开关&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;不需要&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;--features=resource-indicators&lt;/code&gt;（26.7.4 为 EXPERIMENTAL）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;token 的 &lt;code&gt;aud&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;取决于客户端请求了哪些 scope，可能是多个值&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;只剩 &lt;code&gt;resource&lt;/code&gt; 对应的单值（多值会被覆盖）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;失败模式&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;客户端没请求 scope → &lt;code&gt;aud&lt;/code&gt; 缺失 → RS 401&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;resource&lt;/code&gt; 解析不到客户端 → &lt;code&gt;invalid_target&lt;/code&gt;（token 根本不签发）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;合规状态&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;官方文档认可，但 RFC 8707 那一行仍是 Not supported&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;实现已合入（&#13;&#10;&#13;&#10;&lt;a class="link link--text" href="https://github.com/keycloak/keycloak/pull/46763" rel="external"&gt;PR #46763&lt;/a&gt;），文档未发布（&#13;&#10;&#13;&#10;&lt;a class="link link--text" href="https://github.com/keycloak/keycloak/issues/47127" rel="external"&gt;#47127&lt;/a&gt; 仍 open）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;官方文档给出的做法是路径 A：为 MCP server 声明的每个 scope 建一个 client scope，每个 scope 里放一个 Audience mapper，&lt;em&gt;Included Custom Audience&lt;/em&gt; 填 MCP server 的 URL（例如 &lt;code&gt;https://example.com/mcp&lt;/code&gt;）。客户端请求哪些 scope，&lt;code&gt;aud&lt;/code&gt; 里就有对应值。这条路能跑通，因为 MCP 客户端会从 RFC 9728 Protected Resource Metadata 里读取 &lt;code&gt;scopes_supported&lt;/code&gt; 并请求这些 scope——&lt;strong&gt;如果 MCP server 没在元数据里声明 scope，客户端就不会请求，mapper 也就不会触发&lt;/strong&gt;，这是路径 A 最常见的哑火原因。&lt;/p&gt;</description></item><item><title>Keycloak --optimized 启动失败：IAM 构建期选项与运行期选项的边界</title><link>https://idaas.xlabs.club/blog/keycloak-optimized-build-options/</link><pubDate>Thu, 24 Sep 2026 22:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/blog/keycloak-optimized-build-options/</guid><description>容器里给 Keycloak 挂 KC_DB、KC_METRICS_ENABLED 却启动失败或选项不生效，多数是 build-time 与 runtime 选项混用。这篇把校验逻辑、报错原文、版本差异、正确镜像构建方式和回滚讲清楚。</description></item><item><title>Keycloak Kerberos/SPNEGO 对接 AD 域：IAM 内网免登配置与排错</title><link>https://idaas.xlabs.club/blog/keycloak-kerberos-spnego-ad-sso/</link><pubDate>Thu, 24 Sep 2026 23:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/blog/keycloak-kerberos-spnego-ad-sso/</guid><description>内网免登不是打开一个开关：SPN 必须与浏览器访问的地址一致、keytab 必须与 AD 账号当前密钥一致、krbPrincipalAttribute 决定票据里的用户怎么落到目录里。这篇给出三段配置、验证命令、错误对照表与只回退一层的回滚顺序。</description></item><item><title>Keycloak 身份代理登出验签：CVE-2026-18569 与 26.8 升级准备</title><link>https://idaas.xlabs.club/blog/keycloak-broker-logout-token-validation/</link><pubDate>Fri, 25 Sep 2026 21:00:00 +0800</pubDate><guid>https://idaas.xlabs.club/blog/keycloak-broker-logout-token-validation/</guid><description>把 OIDC IdP 的「Validate Signatures」关掉，会连带放过身份代理方向的登出令牌：26.7.4 及更早接受 alg=none 的伪造登出令牌（CVE-2026-18569）。修复 PR #52171 尚未合入，登记在 26.8.0 升级说明里——升级前必须补上公钥或 JWKS，否则上游登出传播会在升级后失效。</description></item></channel></rss>