看来我误解了spi应该如何使用Keycloak XML配置。根据我(非常快速地)浏览Keycloak源代码,似乎任何使用<spi name=xx><provider
都会导致自定义jar文件无法提供该SPI的替代实现。这似乎不太可能。
我正在尝试使用Keycloak的主机名SPI。我已经构建了我的ProviderFactory和我的Provider,我可以从调试keycloak中看到我的META-INF/services/org.keycloak.urls.HostnameProviderFactory
文件正在加载。我还看到我的工厂类正在被加载到JVM中,并且调用了无参数构造函数。
然而,工厂从未显示在可用工厂列表中,并且使用session.getKeycloakSessionFactory().getProviderFactory(HostnameProvider.class, "my-id");
直接调用它返回null。
从跟踪Keycloak看来,我的困惑与我使用的配置XML文件已经定义了<spi name="hostname"><provider name="default" ...
这一事实有关。
在ProviderManager#load(Spi,String)
中,我看到我的自定义工厂正在加载,但因为它没有default
的providerId,所以它被忽略了。这是由DefaultKeycloakSessionFactory#loadFactories(ProviderManager)
调用的,它有一个很大的if-else,主要区别在于它如何处理在配置文件中找到的提供程序。如果找到一个提供程序,它只加载与配置文件中找到的相同名称的SPI实现,否则将加载所有SPI实现。
你只需要在standalone.xml中将你的自定义提供程序设置为默认提供程序:
<spi name="hostname">
<default-provider>my-id</default-provider>
<provider name="my-id" enabled="true">
<properties>
...
</properties>
</provider>
</spi>