第 5 章 服务供应商接口(SPI)
Red Hat build of Keycloak 旨在覆盖大多数用例,而无需自定义代码,但我们也希望它可以被自定义。为了实现此红帽构建的 Keycloak,有许多服务提供商接口(SPI),您可以自行实施供应商。
5.1. 实施 SPI 复制链接链接已复制到粘贴板!
要实施 SPI,您需要实施其 ProviderFactory 和 Provider 接口。您还需要创建服务配置文件。
例如,要实现 Theme Selector SPI,您需要实现 ThemeSelectorProviderFactory 和 ThemeSelectorProvider,并提供文件 META-INF/services/org.keycloak.theme.ThemeSelectorProviderFactory
。
ThemeSelectorProviderFactory 示例:
建议您的供应商工厂实现通过方法 getId ()
返回唯一 id。但是,在 Overriding providers 部分所述,这个规则可能存在一些例外。
红帽构建的 Keycloak 创建一个供应商工厂实例,以便可以存储多个请求的状态。通过调用每个请求的工厂上的 create 来创建供应商实例,因此这些实例应该是轻量级的对象。
ThemeSelectorProvider 示例:
服务配置文件示例(META-INF/services/org.keycloak.theme.ThemeSelectorProviderFactory
):
org.acme.provider.MyThemeSelectorProviderFactory
org.acme.provider.MyThemeSelectorProviderFactory
要配置您的供应商,请参阅配置供应商 章节。
例如,要配置供应商,您可以设置选项,如下所示:
bin/kc.[sh|bat] --spi-theme-selector-my-theme-selector-enabled=true --spi-theme-selector-my-theme-selector-theme=my-theme
bin/kc.[sh|bat] --spi-theme-selector-my-theme-selector-enabled=true --spi-theme-selector-my-theme-selector-theme=my-theme
然后,您可以在 ProviderFactory
init 方法中检索配置:
public void init(Config.Scope config) { String themeName = config.get("theme"); }
public void init(Config.Scope config) {
String themeName = config.get("theme");
}
如果需要,您的供应商也可以查找其他供应商。例如:
5.1.1. 覆盖内置供应商 复制链接链接已复制到粘贴板!
如前文所述,建议您使用 ProviderFactory
实现的唯一 ID。但是,同时,覆盖红帽构建的 Keycloak 内置供应商会很有用。推荐方法是带有唯一 ID 的 ProviderFactory 实现,然后为实例设置默认供应商,如 配置提供程序 章节中所述。另一方面,这可能无法始终实现。
例如,当您需要对默认 OpenID Connect 协议进行一些自定义,并希望覆盖默认的 OIDCLoginProtocolFactory
实现的 Keycloak 实现时,您需要保留相同的 providerId。例如,OIDC 协议众所周知的端点,各种因素依赖于开放连接协议工厂的 ID。
在这种情况下,强烈建议您实施自定义实施的方法 order ()
,并确保其顺序高于内置实施。
如果有多个具有相同供应商 ID 的实现,则红帽构建 Keycloak 运行时只会使用具有最高顺序的那一个。
5.1.2. 在控制台中显示您的 SPI 实施的信息 复制链接链接已复制到粘贴板!
有时,向红帽构建的 Keycloak 管理员显示有关供应商的额外信息会很有用。您可以显示供应商构建时间信息(例如,当前安装的自定义供应商版本)、提供商的当前配置(例如您的供应商与之通信的远程系统的 url)或一些操作信息(来自您的供应商的远程系统平均响应时间)。红帽构建的 Keycloak 管理控制台提供了 Server Info 页面来显示此类信息。
若要显示您的供应商的信息,最好在 ProviderFactory 中实施 org.keycloak.provider.ServerInfoAware
接口。
ProviderFactory
来自上例的 MyThemeSelectorProviderFactory
的实现示例: