第 6 章 服务提供商接口(SPI)
Red Hat build of Keycloak 旨在覆盖大多数用例,而无需自定义代码,但我们也希望它可以被自定义。为了实现此红帽构建的 Keycloak,有许多服务提供商接口(SPI),您可以自行实施供应商。
6.1. 实施 SPI 复制链接链接已复制到粘贴板!
要实施 SPI,您需要实施其 ProviderFactory 和 Provider 接口。您还需要创建服务配置文件。
例如,要实施 Theme Selector SPI,您需要实施 ThemeSelectorProviderFactory 和 ThemeSelectorProviderFactory,并提供文件 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");
}
如果需要,您的供应商也可以查找其他供应商。例如:
6.1.1. 覆盖内置供应商 复制链接链接已复制到粘贴板!
如前文所述,建议您使用 ProviderFactory
实现的唯一 ID。但是,同时,覆盖红帽构建的 Keycloak 内置供应商会很有用。建议的做法是使用唯一 ID 的 ProviderFactory 实施,然后实例用于设置 配置提供程序一章中所述的默认提供程序。另一方面,这可能无法始终实现。
例如,当您需要对默认 OpenID Connect 协议进行一些自定义,并希望覆盖默认的 OIDCLoginProtocolFactory
实现的 Keycloak 实现时,您需要保留相同的 providerId。例如,OIDC 协议众所周知的端点,各种因素依赖于开放连接协议工厂的 ID。
在这种情况下,强烈建议您实施自定义实施的方法 order ()
,并确保其顺序高于内置实施。
如果有多个具有相同供应商 ID 的实现,则红帽构建 Keycloak 运行时只会使用具有最高顺序的那一个。
6.1.2. 在管理门户中显示来自您的 SPI 实现的信息 复制链接链接已复制到粘贴板!
有时,向红帽构建的 Keycloak 管理员显示有关供应商的额外信息会很有用。您可以显示供应商构建时间信息(例如,当前安装的自定义供应商版本)、供应商的当前配置(如您的供应商与远程系统通信的 url)或一些操作信息(来自您供应商的远程系统的响应时间)。红帽构建的 Keycloak 管理控制台提供了 Server Info 页面来显示此类信息。
要显示来自您的提供程序的信息,可以在您的 ProviderFactory 中实施 org.keycloak.provider.ServerInfoAware
接口。
ProviderFactory
上例中的 MyThemeSelectorProviderFactory
的实现示例: