升级依赖后Flyway通过SSL连接PostgreSQL失败问题求助
问题与解决方案:Flyway启用后数据库连接要求客户端证书报错
问题背景
原Java应用基于Spring Boot 2.1.0.RELEASE,使用Postgres JDBC 42.2.5、Flyway 5.2.1,运行正常。升级至Spring Boot 2.7.8、Flyway 7.15.0(保留Postgres JDBC旧版本)后,启用Flyway时应用启动失败,报错FATAL: connection requires a valid client certificate;禁用Flyway则可正常连接数据库。
报错详情
Caused by: org.flywaydb.core.internal.exception.FlywaySqlException: Unable to obtain connection from database: FATAL: connection requires a valid client certificate ------------------------------------------------------------------------------------------------ SQL State : 28000 Error Code : 0 Message : FATAL: connection requires a valid client certificate at org.flywaydb.core.internal.jdbc.JdbcUtils.openConnection(JdbcUtils.java:67) at org.flywaydb.core.internal.jdbc.JdbcConnectionFactory.<init>(JdbcConnectionFactory.java:70) at org.flywaydb.core.Flyway.execute(Flyway.java:504) at org.flywaydb.core.Flyway.migrate(Flyway.java:170) at org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer.afterPropertiesSet(FlywayMigrationInitializer.java:66) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ... 38 common frames omitted Caused by: org.postgresql.util.PSQLException: FATAL: connection requires a valid client certificate at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:514) at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:141) at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:192) at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49) at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195) at org.postgresql.Driver.makeConnection(Driver.java:454) at org.postgresql.Driver.connect(Driver.java:256) at org.springframework.jdbc.datasource.SimpleDriverDataSource.getConnectionFromDriver(SimpleDriverDataSource.java:144) at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:205) at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:169) at org.flywaydb.core.internal.jdbc.JdbcUtils.openConnection(JdbcUtils.java:52) ... 44 common frames omitted
应用配置
spring.datasource.url=jdbc:postgresql://host:5432/db?ssl=true&sslmode=require&sslfactory=org.postgresql.ssl.DefaultJavaSSLFactory spring.datasource.username=user spring.datasource.password= server.ssl.key-store=classpath:certs/keystore-dev.p12 server.ssl.key-store-password=pass server.ssl.key-store-type=PKCS12 server.ssl.key-alias=app-alias server.ssl.protocol=TLS # flyway db migration support spring.flyway.enabled=true
原因分析
- Flyway 7.x与Spring Boot 2.7.x整合时,默认不会复用Spring容器中已配置的
DataSource,而是独立创建数据库连接,导致无法继承Spring DataSource的SSL连接配置。 server.ssl.*配置仅用于Web服务器的SSL证书,并非数据库客户端连接所需的证书配置,Flyway的独立连接无法获取到该配置。
解决方案
方案1:强制Flyway复用Spring DataSource
添加配置让Flyway直接使用Spring管理的DataSource,复用已有的SSL连接逻辑:
spring.flyway.use-datasource=true
该配置在Spring Boot 2.7.x中默认关闭,需显式开启。
方案2:为Flyway单独配置SSL参数
如果方案1无效,可为Flyway单独配置数据库连接的SSL参数:
- 在Flyway的JDBC URL中添加客户端证书信息:
spring.flyway.url=jdbc:postgresql://host:5432/db?ssl=true&sslmode=require&sslfactory=org.postgresql.ssl.DefaultJavaSSLFactory&sslkey=classpath:certs/keystore-dev.p12&sslkeyfactory=PKCS12&sslkeypassword=pass spring.flyway.username=user spring.flyway.password=
- 或通过JVM启动参数全局指定SSL证书存储:
-Djavax.net.ssl.keyStore=classpath:certs/keystore-dev.p12 -Djavax.net.ssl.keyStorePassword=pass -Djavax.net.ssl.keyStoreType=PKCS12
此方式下Flyway和Spring DataSource都会使用同一套证书配置。
方案3:升级Postgres JDBC驱动版本
保留旧版Postgres JDBC 42.2.5可能存在兼容性问题,建议升级至Spring Boot 2.7.8兼容的版本(如42.3.9,可从spring-boot-dependencies 2.7.8中获取),新版本驱动在SSL连接处理上更完善,能更好适配Flyway 7.x。
内容的提问来源于stack exchange,提问作者amaurinorato
相关产品推荐
相关产品推荐

