由于这个 PR https://github.com/keycloak/keycloak/commit/056ba75a72b1595ca9fa471f5693201fd5b2c7ae 默认情况下(Keycloak 最新版本 6.0.1),使用 InfinispanChangelogBasedTransaction.java 的 Infinispan Connection SPI 有一个非常特殊的使用 CacheDecorator.java 将 skipCacheStore。这意味着无论您是否配置具有持久性的存储,该存储都将被忽略。
为了实现您想要的,除了配置存储之外,您还必须在此处自定义大部分 SPI https://github.com/keycloak/keycloak/tree/master/model/infinispan/src/main/resources/META-INF/services 以确保 Keycloak 将使用缓存存储。
这也不是一件容易的事,因为这个过程涉及很多好处,例如,由于 Keycloak 使用 Jboss 的 Marshaller,如果你自定义这个 SPI,你将不得不带上大部分 org.keycloak.models.sessions.infinispan 包并注册您的模块以确保 Wildfly 能够看到要编组的实体。
另外一点是,你应该在Redis中配置大部分缓存指向一个公共数据库,除了authenticationSessions不能和sessions在同一个数据库中,否则会出现类似@的冲突987654330@ 已找到,但应为 SessionEntityWrapper。
要恢复,过程会很痛苦,但如果你敢去做,我就是这样实现的:
- 引入了一个自定义 InfinispanConnectionProviderFactory,以便完全能够使用 infinispan 配置,然后像这样配置我的容器:
private Configuration getRedisConfiguration(int database) {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.persistence()
.passivation(false)
.addStore(RedisCacheStoreConfigurationBuilder.class)
.ignoreModifications(false)
.fetchPersistentState(false)
.purgeOnStartup(false)
.preload(false)
.shared(true)
.addProperty("host", System.getenv("REDIS_HOST"))
.addProperty("port", System.getenv("REDIS_PORT"))
.addProperty("database", String.valueOf(database));
return cb.build();
}
您看到的RedisCacheStoreConfigurationBuilder 基本上是原始存储的精简版本,但我不需要哨兵或服务器模式,我只想连接到主机、端口和数据库。
然后我基本上复制了org.keycloak.models.sessions.infinispan,删除了与删除缓存相关的所有内容,而不是正常使用没有装饰器的缓存来跳过CacheStore。
如果我能提供帮助,请告诉我,我会准备一篇文章,详细说明如何执行此操作,其中还包括一个包含我正在谈论的代码的存储库。如果有人还在尝试这个,请告诉我更多信息。