Keycloak 23移除离线令牌独立存储特性后的外置存储替代方案咨询
解决方案:通过Keycloak SPI实现离线令牌外置存储
完全可以通过实现Keycloak的SPI来替代移除的独立数据库存储特性,无需依赖持久化Infinispan缓存服务器。核心是自定义实现OfflineTokenStoreProvider SPI,以下是具体步骤:
1. 实现核心SPI接口
Keycloak提供了OfflineTokenStoreProvider接口,负责离线令牌的CRUD操作。你需要重写该接口的核心方法,将逻辑指向你的外置数据库:
public class CustomOfflineTokenStore implements OfflineTokenStoreProvider { private final KeycloakSession session; private final DataSource dataSource; public CustomOfflineTokenStore(KeycloakSession session, DataSource dataSource) { this.session = session; this.dataSource = dataSource; } @Override public void createOfflineToken(OfflineToken token) { // 实现将token序列化后写入外置数据库的逻辑 String serializedToken = serializeToken(token); // 执行JDBC插入操作 } @Override public OfflineToken getOfflineToken(String tokenId) { // 从外置数据库读取序列化的token,反序列化为OfflineToken对象 String serializedToken = fetchSerializedTokenFromDB(tokenId); return deserializeToken(serializedToken); } // 重写其他必要方法:removeOfflineToken、findOfflineTokens等 // ... private String serializeToken(OfflineToken token) { // 使用Jackson或Keycloak内置序列化工具实现 // 示例:ObjectMapper mapper = new ObjectMapper(); return mapper.writeValueAsString(token); } private OfflineToken deserializeToken(String serialized) { // 反序列化逻辑 } }
2. 实现Provider工厂类
工厂类负责创建自定义Provider实例,并加载配置参数:
public class CustomOfflineTokenStoreFactory implements OfflineTokenStoreProviderFactory { private DataSource dataSource; @Override public OfflineTokenStoreProvider create(KeycloakSession session) { return new CustomOfflineTokenStore(session, dataSource); } @Override public void init(Config.Scope config) { // 从Keycloak配置中读取外置数据库连接参数,初始化DataSource String dbUrl = config.get("db-url"); String username = config.get("db-username"); String password = config.get("db-password"); // 初始化HikariCP或其他连接池 dataSource = createDataSource(dbUrl, username, password); } @Override public String getId() { // 自定义Provider标识,后续配置会用到 return "custom-offline-token-store"; } }
3. 注册与部署
- 在你的JAR包中添加
META-INF/services/org.keycloak.models.OfflineTokenStoreProviderFactory文件,内容为你的工厂类全限定名 - 将JAR包放入Keycloak的
providers目录 - 修改Keycloak配置(如
keycloak.conf),指定使用自定义Provider:spi-offline-token-store-provider=custom-offline-token-store spi-offline-token-store-custom-offline-token-store-db-url=jdbc:mysql://your-db-host:3306/offline_tokens spi-offline-token-store-custom-offline-token-store-db-username=db-user spi-offline-token-store-custom-offline-token-store-db-password=db-pass - 重启Keycloak生效
关键注意事项
- 事务兼容:确保数据库操作与Keycloak的事务上下文同步,可通过
session.getTransactionManager()获取事务管理器处理事务边界 - 索引优化:在外置数据库中为令牌ID、用户ID等字段创建索引,提升查询性能
- 序列化兼容性:使用稳定的序列化方式,避免Keycloak版本升级导致令牌无法反序列化
- API适配:严格遵循Keycloak 23版本的SPI接口规范,避免因API变更导致的兼容问题
内容的提问来源于stack exchange,提问作者Shane Rowatt
相关产品推荐
相关产品推荐

