从Java连接PostgreSQL遇致命认证错误,bash连接正常求助
问题根源:PostgreSQL的两种连接认证规则差异
你遇到的问题本质是终端的psql连接和Java的JDBC连接走的是PostgreSQL不同的认证通道:
- 你在bash里敲
psql -U postgres时,PostgreSQL默认用的是本地套接字连接(不需要走TCP/IP端口),这种连接的认证规则由pg_hba.conf里的local条目控制。 - 而Java代码用
jdbc:postgresql://localhost:5432/...是走TCP/IP连接,对应的是pg_hba.conf里的host条目,认证规则完全不一样。
具体排查与解决步骤
1. 先查看你的pg_hba.conf配置
这个文件的位置取决于你的PostgreSQL安装路径,常见路径比如:
- Ubuntu/Debian:
/var/lib/postgresql/<你的PG版本>/main/pg_hba.conf - CentOS/RHEL:
/var/lib/pgsql/data/pg_hba.conf - 手动编译安装:
/usr/local/pgsql/data/pg_hba.conf
打开后你大概率会看到类似这样的配置:
# 本地套接字连接(终端psql用这个) local all postgres peer # TCP/IP本地连接(Java JDBC用这个) host all all 127.0.0.1/32 scram-sha-256
简单解释:
peer认证是让PostgreSQL匹配你的Linux系统用户名和PG用户名(比如你用Linux的postgres用户登录,或者sudo切换到该用户,就能直接连接无需密码)。scram-sha-256(或者旧版的md5)是密码认证,必须提供正确的PG用户密码才能通过。
2. 两种解决思路
思路一:让本地TCP/IP连接也免密码(适合开发环境)
编辑pg_hba.conf,把针对127.0.0.1/32的postgres用户条目改成trust或者peer:
host all postgres 127.0.0.1/32 trust
改完后必须重启PostgreSQL服务才能生效,比如:
# Ubuntu/Debian sudo systemctl restart postgresql # CentOS/RHEL sudo systemctl restart postgresql-<版本号>
提醒:
trust认证相当于完全放开本地TCP/IP的postgres用户访问,安全性很低,只适合本地开发测试用,生产环境绝对不能这么做!
思路二:设置postgres密码,Java代码用正确密码连接(生产环境推荐)
这是更安全的做法:
- 先在终端连接PG:
psql -U postgres - 执行SQL设置密码:
ALTER USER postgres PASSWORD '你的安全密码';
- 修改Java代码里的连接字符串,把空密码替换成你刚设置的密码:
con = DriverManager.getConnection("jdbc:postgresql://localhost:5432/mydb?autoReconnect=true", "postgres", "你的安全密码");
3. 额外小坑提醒
如果你的系统优先用IPv6,那Java可能会通过::1(IPv6的本地回环)连接,这时候你需要检查pg_hba.conf里的IPv6条目:
host all all ::1/128 scram-sha-256
要么把这条也改成trust(仅限开发环境),要么在Java的JDBC URL里指定用IPv4:jdbc:postgresql://127.0.0.1:5432/mydb?autoReconnect=true
内容的提问来源于stack exchange,提问作者springbooter99




