如何在Keycloak中验证多租户Azure Entra ID的Issuer值
多租户Azure Entra ID接入Keycloak的动态Issuer验证解决方案
核心问题分析
Keycloak默认OIDC身份提供商的Issuer验证是静态匹配逻辑,而多租户Azure Entra ID返回的token中,Issuer固定为https://login.microsoftonline.com/<租户ID>/v2.0格式,每个租户的Issuer都唯一。Keycloak不识别{tenantid}这类模板占位符,直接留空Issuer字段会跳过验证,存在被伪造token攻击的安全风险。
可行解决方案
1. 自定义OIDC身份提供商扩展(最彻底方案)
通过重写Keycloak的Issuer验证逻辑实现动态校验:
- 新建Keycloak扩展项目,继承
OidcIdentityProvider类,重写validateIssuer方法 - 在重写的方法中,提取token里的
iss字段,用正则表达式^https:\/\/login\.microsoftonline\.com\/[0-9a-f-]+\/v2\.0$验证格式合法性 - 可选增强:调用对应租户的微软发现端点
https://login.microsoftonline.com/<租户ID>/v2.0/.well-known/openid-configuration,确认该Issuer的配置有效 - 将扩展打包为JAR,放到Keycloak的
providers目录,重启后使用这个自定义身份提供商配置多租户Entra ID
2. 用Keycloak脚本扩展实现校验(零开发成本)
利用Keycloak内置脚本功能添加动态验证步骤:
- 进入Keycloak控制台,创建自定义身份验证流程,在「Post Login」阶段添加「Script Authenticator」执行器
- 编写JavaScript脚本实现Issuer校验,示例代码:
var authSession = session.getContext().getAuthenticationSession(); var federatedIdentity = authSession.getUser().getFederatedIdentity("your-oidc-provider-id"); var iss = federatedIdentity.getToken().getIssuer(); var validIssuerRegex = /^https:\/\/login\.microsoftonline\.com\/[0-9a-f-]+\/v2\.0$/; if (!validIssuerRegex.test(iss)) { throw new Error("Invalid issuer detected: " + iss); } - 将该流程绑定到目标客户端,确保每次登录都执行Issuer校验
3. 动态客户端注册(备选,适用于租户数量可控场景)
如果租户数量并非完全不可控,可为每个租户单独配置Keycloak客户端:
- 让租户通过Entra ID动态客户端注册功能,或手动为每个租户创建Keycloak客户端
- 每个客户端的Issuer字段填写对应租户的
https://login.microsoftonline.com/<租户ID>/v2.0 - 此方式维护成本较高,仅适合租户数量较少的场景
排查建议
- 确认Entra ID应用为多租户模式:检查应用「支持的账户类型」是否设置为「任何组织目录中的账户」
- 开启Keycloak调试日志:在配置文件中设置日志级别为
DEBUG,查看OIDC提供商的Issuer验证细节,确认token中Issuer与配置值的差异 - 验证正则表达式覆盖范围:微软租户ID为带连字符的GUID格式,确保正则能匹配所有合法格式
- 检查Keycloak版本:部分新版本对多租户OIDC场景有优化,尝试升级到最新稳定版
内容的提问来源于stack exchange,提问作者SRA
相关产品推荐
相关产品推荐

