Keycloak/Liquibase: ERROR: column "salt" is of type oid but expression is of type bytea

Keycloak/Liquibase: ERROR: column "salt" is of type oid but expression is of type bytea

我正在使用 https://github.com/thomasdarimont/spring-boot-keycloak-server-example 到 运行 keycloak 实例。我尝试从 h2 切换到 PostgreSQL,出现管理员帐户创建屏幕,但创建初始管理员帐户失败并显示:

Hibernate:
insert
into
    CREDENTIAL
    (ALGORITHM, COUNTER, CREATED_DATE, DEVICE, DIGITS, HASH_ITERATIONS, PERIOD, SALT, TYPE, USER_ID, VALUE, ID)
values
    (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [VARCHAR] - [pbkdf2-sha256]
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [INTEGER] - [0]
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [3] as [BIGINT] - [1504025461373]
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [4] as [VARCHAR] - [null]
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [5] as [INTEGER] - [0]
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [6] as [INTEGER] - [27500]
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [7] as [INTEGER] - [0]
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [8] as [VARBINARY] - [[B@708e0a84]
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [9] as [VARCHAR] - [password]
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [10] as [VARCHAR] - [32e0eb33-091b-4791-a923-4cc9fc976371]
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [11] as [VARCHAR] - [CBJ4e+h56g1I0uxyexae7p5xJ2xLILGh8Hkx4t/jGSZ74XHbqDmGLW2vfPyIUl17puB+hihu3OpwNJSjT+LRgw==]
2017-08-29 18:51:01.482 TRACE 7020 --- [io-20909-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [12] as [VARCHAR] - [738017b1-ff7b-47cf-a2e9-7c9f6055f0aa]
2017-08-29 18:51:01.498  WARN 7020 --- [io-20909-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 42804
2017-08-29 18:51:01.498 ERROR 7020 --- [io-20909-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: column "salt" is of type oid but expression is of type bytea
Hint: You will need to rewrite or cast the expression.
Position: 168

我在 keycloak-server.json 中调整了 connectionsJpa 设置如下:

"connectionsJpa": {
    "provider": "default",
    "default": {
        "url": "${env.KEYCLOAK_DATABASE_URL:jdbc:postgresql://server/testdb}",
        "driver": "${keycloak.connectionsJpa.driver:org.postgresql.Driver}",
        "driverDialect": "${keycloak.connectionsJpa.driverDialect:org.hibernate.dialect.PostgreSQLDialect}",
        "user": "${keycloak.connectionsJpa.user:user}",
        "password": "${keycloak.connectionsJpa.password:password}",
        "initializeEmpty": true,
        "migrationStrategy": "update",
        "showSql": "${keycloak.connectionsJpa.showSql:true}",
        "formatSql": "${keycloak.connectionsJpa.formatSql:true}",
        "globalStatsInterval": "${keycloak.connectionsJpa.globalStatsInterval:-1}"
    }
},

看来,从Liquibase 3.5.2开始,blob类型生成PostgreSQL类型oid,不再是bytea了。参见 CORE-1863

有人有解决方案吗?

问题似乎是 Liquibase 3.5.2 或更高版本将导致 public.credential.salt 列以 oid 类型创建,而 Keycloak 期望它是 bytea。

解决方案是恢复到早期版本的 Liquibase(我推荐 3.4.1,因为这是 Keycloak 通常使用的版本)。您可以通过将 liquibase 版本添加到项目主 pom.xml

的版本属性中来完成此操作
<properties>
    ......
    <liquibase.version>3.4.1</liquibase.version>
</properties>

在此之后不要忘记删除旧的 Keycloak 数据库,以便 Keycloak 可以在您重新启动时使用正确的盐类型创建它。