配置XML已定义hostname spi时自定义Keycloak Hostname SPI不生效咨询
核心原理说明
你追踪源码得到的结论是Keycloak的标准设计逻辑:当XML配置中为某SPI显式声明了<provider>子节点时,Keycloak只会加载该SPI下**显式配置且enabled="true"**的provider实现,未在配置中声明的实现哪怕被类加载器加载,也会被过滤排除,该设计的目的是方便管理员精准控制服务加载的实现类,避免无关实现被意外启用。
解决方案
方案1:显式添加自定义provider配置(最推荐)
直接修改Keycloak的核心配置文件(通常为standalone.xml或standalone-ha.xml),在hostname SPI的配置节点下新增你自定义实现的配置项,同时可按需修改默认使用的provider:
<!-- 把default-provider改为你自定义provider的ID,即可将其设为该SPI的默认实现 --> <spi name="hostname" default-provider="my-id"> <!-- 原有default provider的配置可按需保留或删除 --> <provider name="default" enabled="true"> <!-- 原有default provider的配置参数 --> </provider> <!-- 新增自定义provider配置,name属性必须和你实现类getId()返回值完全一致 --> <provider name="my-id" enabled="true"> <!-- 此处可添加自定义provider需要的专属配置参数,无参数可省略该子节点 --> </provider> </spi>
修改配置后重启Keycloak即可生效,此时调用session.getKeycloakSessionFactory().getProviderFactory(HostnameProvider.class, "my-id");即可正常获取到你的自定义工厂实例。
方案2:移除SPI下所有provider的显式配置
如果你不需要对该SPI的任意provider做自定义参数配置,也可以直接删除<spi name="hostname">节点下的所有<provider>子节点,此时Keycloak会自动加载classpath下所有该SPI的实现,你的自定义实现也会被纳入可用列表。
验证方式
重启Keycloak后进入管理员控制台,打开「服务器信息」页面切换到「Provider」标签,在hostname分类下可查看到你自定义的provider ID,即代表加载成功。
注意:配置中
<provider>的name属性值必须和你自定义HostnameProviderFactory类中getId()方法的返回值完全一致,大小写敏感。
内容的提问来源于stack exchange,提问作者Hamy

