MySQL密码正确但是启动报错Unable to create initial connections of pool.Access denied for user ‘root‘@‘localhost

在本地启动SpringBoot项目时,尽管确认了MySQL的密码正确,但依然遇到启动错误'Unable to create initial connections of pool'。尝试修改Yml配置文件和检查username/password未果。最终通过在MySQL的my.ini配置文件末尾添加'skip-grant-tables'并重启服务解决了因执行SQL语句出错导致的登录权限问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

最近导入了一个SpringBoot项目,在本地配置好之后,项目启动一直报错:

2020-12-17 15:46:42.136 ERROR 19320 --- [restartedMain] o.a.tomcat.jdbc.pool.ConnectionPool      : Unable to create initial connections of pool.

java.sql.SQLException: Access denied for user 'root'@'localhost' (<
<think>我们遇到的问题是在使用Tomcat JDBC连接池时,尝试初始化数据库连接失败,抛出了一个异常:`java.sql.SQLNonTransientConnectionException:Public KeyRetrievalis notallowed`这个异常通常发生在使用MySQLConnector/J8.0以上版本连接MySQL数据库时,特别是当用户账户使用了caching_sha2_password认证插件(MySQL8.0默认)并且SSL连接没有启用的情况下。 ###原因分析:MySQL8.0默认使用`caching_sha2_password`作为身份验证插件。当客户端尝试连接时,如果未使用SSL,客户端可能会尝试从服务器获取公钥以进行密码交换。但是,如果客户端配置中禁止公钥检索(`allowPublicKeyRetrieval=false`,这是默认设置),则会导致连接失败。###解决方案:有几种方法可以解决这个问题:1.**启用公钥检索**:在连接字符串中设置`allowPublicKeyRetrieval=true`。但请注意,这可能会降低安全性,因为允许客户端从服务器获取公钥。2.**使用SSL连接**:通过设置`useSSL=true`来启用SSL连接,这样通信就是加密的,并且不会触发公钥检索的问题。 3. **更改MySQL用户的认证插件**:将用户的认证插件改为旧版的`mysql_native_password`,这样就不需要公钥交换了。 ###推荐方案:通常,推荐使用SSL连接(方案2)以增强安全性。但如果是在测试环境或者内部安全网络,也可以考虑方案1。方案3则涉及到修改MySQL用户设置,可能会影响其他应用。 ###配置示例:在Tomcat JDBC连接池的配置中(比如在context.xml或应用配置文件中),我们需要修改数据库连接URL。 ####方案1:允许公钥检索在连接URL中添加`allowPublicKeyRetrieval=true`参数,例如:```jdbc:mysql://your-mysql-server:3306/your_database?allowPublicKeyRetrieval=true``` ####方案2:启用SSL在连接URL中添加`useSSL=true`参数,例如:``` jdbc:mysql://your-mysql-server:3306/your_database?useSSL=true``` 如果同时需要允许公钥检索和SSL,可以这样设置(不推荐,除非必要): ```jdbc:mysql://your-mysql-server:3306/your_database?allowPublicKeyRetrieval=true&useSSL=true```###注意:-如果使用方案1,请确保了解安全风险。公钥检索可能会被中间人攻击利用,因此生产环境建议使用SSL。 -如果MySQL服务器没有配置SSL,那么设置`useSSL=true`可能会导致连接失败,因为客户端要求加密连接而服务器不支持。此时,可以考虑使用`useSSL=false`,但这样会降低安全性。不过,在MySQL8.0中,如果使用`caching_sha2_password`并且没有SSL,则必须允许公钥检索(即方案1)或者使用方案3。###方案3:更改认证插件(可选) 在MySQL服务器上执行: ```sqlALTER USER'your_username'@'%' IDENTIFIEDWITH mysql_native_password BY'your_password';FLUSHPRIVILEGES;``` 然后,在连接字符串中无需特殊设置,但注意这会使该用户使用旧的认证方式。 ###在Tomcat中的配置示例:假设你是在Tomcat的context.xml中配置数据源,修改URL属性如下(以方案1为例):```xml<Resource name="jdbc/yourDB"auth="Container"type="javax.sql.DataSource"driverClassName="com.mysql.cj.jdbc.Driver"url="jdbc:mysql://your-mysql-server:3306/your_database?allowPublicKeyRetrieval=true&useSSL=false"username="your_username"password="your_password"...其他配置.../> ```注意:在XML中,&符号需要转义为`&`。###总结: 根据你的安全需求和MySQL服务器配置,选择上述一种解决方案。通常,生产环境推荐启用SSL(方案2)并配合适当的认证方式。###相关问题: §§相关问题§§: 1.如何配置Tomcat JDBC连接池?2.MySQL8.0的默认认证插件是什么?它和旧版插件有什么不同?3.Java应用中,除了修改连接字符串,还有哪些方法可以解决数据库连接问题?4.如何为MySQL服务器配置SSL?</think>### 解决方案:解决 "Public Key Retrieval is not allowed" 错误 这个错误发生在 Java 应用(如 Tomcat)连接 MySQL 8.0+ 数据库时,主要原因是 MySQL 8.0 默认使用 `caching_sha2_password` 认证插件,而客户端需要额外配置才能正确处理这种认证方式。以下是详细的解决方案: --- #### **方法 1:在 JDBC URL 中添加连接参数(推荐)** 在数据库连接 URL 中添加以下参数: ```url allowPublicKeyRetrieval=true&useSSL=false ``` **修改后的 JDBC URL 示例:** ```java jdbc:mysql://your-server:3306/your_db?allowPublicKeyRetrieval=true&useSSL=false ``` **参数说明:** - `allowPublicKeyRetrieval=true`:允许客户端从服务器获取公钥(必需) - `useSSL=false`:禁用 SSL(仅在测试环境使用;生产环境应启用 SSL) --- #### **方法 2:修改 MySQL 用户认证插件(需要数据库权限)** 将用户认证插件改为旧版 `mysql_native_password`: ```sql -- 修改用户认证方式 ALTER USER 'your_username'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; -- 刷新权限 FLUSH PRIVILEGES; ``` --- #### **方法 3:完整配置示例(Tomcat context.xml)** 在 Tomcat 的 `context.xml` 中配置数据源: ```xml <Resource name="jdbc/yourDB" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/your_db?allowPublicKeyRetrieval=true&useSSL=false" username="dbuser" password="dbpass" maxTotal="20" maxIdle="10" /> ``` --- #### **方法 4:Java 代码配置(适用于程序化连接池)** ```java import org.apache.tomcat.jdbc.pool.PoolProperties; PoolProperties props = new PoolProperties(); props.setUrl("jdbc:mysql://localhost:3306/your_db"); props.addConnectionProperty("allowPublicKeyRetrieval", "true"); // 关键参数 props.addConnectionProperty("useSSL", "false"); props.setDriverClassName("com.mysql.cj.jdbc.Driver"); props.setUsername("dbuser"); props.setPassword("dbpass"); DataSource dataSource = new DataSource(); dataSource.setPoolProperties(props); ``` --- ### **错误原因详解** 1. **MySQL 8.0 认证变更** MySQL 8.0 默认使用 `caching_sha2_password` 插件,需要 RSA 公钥交换密码。 2. **客户端安全限制** JDBC 驱动默认禁止公钥检索(`allowPublicKeyRetrieval=false`),以防止中间人攻击。 3. **SSL 配置影响** 未启用 SSL 时,必须显式允许公钥检索才能建立连接。 --- ### **最佳实践建议** 1. **生产环境** - 启用 SSL:`useSSL=true` - 配合 `allowPublicKeyRetrieval=true`(需评估安全风险) - 使用证书验证(`trustCertificateKeyStoreUrl`) 2. **测试环境** 直接使用 `allowPublicKeyRetrieval=true&useSSL=false` 3. **驱动版本** 确保使用最新的 MySQL Connector/J(≥ 8.0.11): ```xml <!-- Maven 依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值