7.5.2. 供应商工厂实现
现在,供应商类已经完成,我们现在转意供应商工厂类。
public class PropertyFileUserStorageProviderFactory
implements UserStorageProviderFactory<PropertyFileUserStorageProvider> {
public static final String PROVIDER_NAME = "readonly-property-file";
@Override
public String getId() {
return PROVIDER_NAME;
}
首先要注意的是,在实施 UserStorageProviderFactory 类时,您必须将 concrete 供应商类实现作为模板参数传递。在这里,我们指定我们之前定义的供应商类: PropertyFileUserStorageProvider。
如果没有指定 template 参数,您的供应商将无法正常工作。运行时进行类内省,以确定提供程序实施 的功能接口。
getId () 方法标识运行时中的工厂,当您要为域启用用户存储供应商时,也会是 admin 控制台中显示的字符串。
7.5.2.1. 初始化 复制链接链接已复制到粘贴板!
private static final Logger logger = Logger.getLogger(PropertyFileUserStorageProviderFactory.class);
protected Properties properties = new Properties();
@Override
public void init(Config.Scope config) {
InputStream is = getClass().getClassLoader().getResourceAsStream("/users.properties");
if (is == null) {
logger.warn("Could not find users.properties in classpath");
} else {
try {
properties.load(is);
} catch (IOException ex) {
logger.error("Failed to load users.properties file", ex);
}
}
}
@Override
public PropertyFileUserStorageProvider create(KeycloakSession session, ComponentModel model) {
return new PropertyFileUserStorageProvider(session, model, properties);
}
UserStorageProviderFactory 接口有可选的 init () 方法,您可以实现。当红帽构建的 Keycloak 启动时,每个供应商工厂只创建一个实例。另外,还会在这些工厂实例上调用 init () 方法。还有一个 postInit () 方法,您也可以实施。调用每个工厂的 init () 方法后,会调用它们的 postInit () 方法。
在 init () 方法实现中,我们从 classpath 找到包含用户声明的属性文件。然后,我们将使用用户名和密码组合来加载 properties 字段。
Config.Scope 参数是通过服务器配置的工厂配置。
例如,使用以下参数运行服务器:
kc.[sh|bat] start --spi-storage-readonly-property-file-path=/other-users.properties
我们可以指定用户属性文件的 classpath,而不是硬编码它。然后,您可以在 PropertyFileUserStorageProviderFactory.init () 中检索配置:
public void init(Config.Scope config) {
String path = config.get("path");
InputStream is = getClass().getClassLoader().getResourceAsStream(path);
...
}