You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:47:24