7.6. 配置技术
PropertyFileUserStorageProvider
示例是一个位聚合。它被硬编码到嵌入在提供程序的 jar 中的属性文件,这并不很有用。我们可能希望使此文件的位置可以为每个提供程序实例进行配置。换句话说,我们可能在多个不同的域中多次重复使用此提供程序,并指向完全不同的用户属性文件。我们还希望在管理控制台 UI 中执行此配置。
UserStorageProviderFactory
还有额外的方法,您可以实现用于处理供应商配置。您描述了您要为每个提供程序配置的变量,而管理控制台会自动呈现通用输入页面来收集此配置。在实施时,回调方法也会在保存配置前验证配置,当第一次创建提供程序以及更新时。UserStorageProviderFactory
从 org.keycloak.component.ComponentFactory
接口继承这些方法。
List<ProviderConfigProperty> getConfigProperties(); default void validateConfiguration(KeycloakSession session, RealmModel realm, ComponentModel model) throws ComponentValidationException { } default void onCreate(KeycloakSession session, RealmModel realm, ComponentModel model) { } default void onUpdate(KeycloakSession session, RealmModel realm, ComponentModel model) { }
ComponentFactory.getConfigProperties ()
方法返回 org.keycloak.provider.ProviderConfigProperty
实例的列表。这些实例声明了呈现和存储提供程序的每个配置变量所需的元数据。
7.6.1. 配置示例
我们来展开我们的 PropertyFileUserStorageProviderFactory
示例,允许您将供应商实例指向磁盘上的特定文件。
PropertyFileUserStorageProviderFactory
public class PropertyFileUserStorageProviderFactory implements UserStorageProviderFactory<PropertyFileUserStorageProvider> { protected static final List<ProviderConfigProperty> configMetadata; static { configMetadata = ProviderConfigurationBuilder.create() .property().name("path") .type(ProviderConfigProperty.STRING_TYPE) .label("Path") .defaultValue("${jboss.server.config.dir}/example-users.properties") .helpText("File path to properties file") .add().build(); } @Override public List<ProviderConfigProperty> getConfigProperties() { return configMetadata; }
ProviderConfigurationBuilder
类是一个很好的帮助程序类,用于创建配置属性列表。在这里,我们指定了一个名为 path
的变量,它是一个字符串类型。在此提供程序的 Admin Console 配置页面中,此配置变量被标记为 Path
,默认值为 ${jboss.server.config.dir}/example-users.properties
。当您将鼠标悬停在此配置选项的工具提示时,它会显示帮助文本,指向属性文件的文件名
。
下面我们将做的下一个操作是验证磁盘上是否存在此文件。除非它指向有效的用户属性文件,我们不想在域中启用此提供程序的实例。为此,我们实施 validateConfiguration ()
方法。
@Override public void validateConfiguration(KeycloakSession session, RealmModel realm, ComponentModel config) throws ComponentValidationException { String fp = config.getConfig().getFirst("path"); if (fp == null) throw new ComponentValidationException("user property file does not exist"); fp = EnvUtil.replace(fp); File file = new File(fp); if (!file.exists()) { throw new ComponentValidationException("user property file does not exist"); } }
validateConfiguration ()
方法提供 组件Model 中的配置变量
,以验证磁盘上是否存在该文件。请注意,使用 org.keycloak.common.util.EnvUtil.replace ()
方法。使用这个方法,包含 ${}
的任何字符串都将用系统属性值替换该值。${jboss.server.config.dir}
字符串对应于服务器的 conf/
目录,这对于本例来说非常有用。
接下来,我们必需做的是删除旧的 init ()
方法。我们这样做,因为用户属性文件将为每个供应商实例是唯一的。我们将此逻辑移到 create ()
方法。
@Override public PropertyFileUserStorageProvider create(KeycloakSession session, ComponentModel model) { String path = model.getConfig().getFirst("path"); Properties props = new Properties(); try { InputStream is = new FileInputStream(path); props.load(is); is.close(); } catch (IOException e) { throw new RuntimeException(e); } return new PropertyFileUserStorageProvider(session, model, props); }
这个逻辑是,由于每个事务都从磁盘读取整个用户属性文件,但希望以简单方式,在配置变量中如何 hook,所以其逻辑都效率较低。
7.6.2. 在管理门户中配置提供程序
现在,启用了配置,您可以在管理控制台中配置供应商时设置 path
变量。