【问题标题】:Connection Java - MySQL : Public Key Retrieval is not allowed连接 Java - MySQL:不允许检索公钥
【发布时间】:2018-10-27 00:53:07
【问题描述】:

我尝试使用连接器 8.0.11 将 MySQL 数据库与 Java 连接起来。一切似乎都很好,但我得到了这个例外:

Exception in thread "main" java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed at
     com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:108) at 
     com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95) at
     com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) at     
     com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:862) at 
     com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:444) at
     com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:230) at
     com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:226) at
     com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:438) at
     com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:146) at
     com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:119) at
     ConnectionManager.getConnection(ConnectionManager.java:28) at
     Main.main(Main.java:8)
 

这是我的连接管理器类:

public class ConnectionManager {

    public static final String serverTimeZone = "UTC";
    public static final String serverName = "localhost";
    public static final String databaseName ="biblioteka";
    public static final int portNumber = 3306;
    public static final String user = "anyroot";
    public static final String password = "anyroot";
    
    public static Connection getConnection() throws SQLException {
    
        MysqlDataSource dataSource = new MysqlDataSource();
    
        dataSource.setUseSSL( false );
        dataSource.setServerTimezone( serverTimeZone );
        dataSource.setServerName( serverName );
        dataSource.setDatabaseName( databaseName );
        dataSource.setPortNumber( portNumber );
        dataSource.setUser( user );
        dataSource.setPassword( password );
        
        return dataSource.getConnection();
    }
}

【问题讨论】:

  • 请提供一些代码:您是如何尝试连接的。异常的堆栈跟踪也会有所帮助。

标签: java mysql exception connector


【解决方案1】:

您应该将客户端选项添加到您的 mysql-connector allowPublicKeyRetrieval=true 以允许客户端自动从服务器请求公钥。请注意,allowPublicKeyRetrieval=True 可能允许恶意代理执行 MITM 攻击以获取明文密码,因此默认为 False,必须显式启用。

https://mysql-net.github.io/MySqlConnector/connection-options/

您也可以尝试在将useSSL=false 用于测试/开发目的时添加它

示例:

jdbc:mysql://localhost:3306/db?allowPublicKeyRetrieval=true&useSSL=false

【讨论】:

  • 嗯,这对我有用,但从安全角度来看,我不确定这些选项的合法性。
  • useSSL=false&allowPublicKeyRetrieval=true 是我在本地主机中尝试从docker_container1 连接到docker_container2_mysql(where mysql is installed) 时才需要的。而从我的主机到docker_container2_mysqluseSSL=false 就足够了。
  • 你能解释一下为什么会这样吗?
  • 我的问题是,直到昨天它还运行良好。一夜之间会发生什么变化?
  • 尝试从对我有用的网址中删除 useSSl=false
【解决方案2】:

jdbc url 用作:

jdbc:mysql://localhost:3306/Database_dbName?allowPublicKeyRetrieval=true&useSSL=false;

PortNo: 3306 在您的配置中可能会有所不同

【讨论】:

  • 这里有一个小修正。连接属性“useSSL”可接受的值为:“TRUE”、“FALSE”、“YES”或“NO”。值'假;'是不可接受的。
【解决方案3】:

我在 Spring Boot 框架上使用以下配置解决了这个问题

spring.datasource.url=jdbc:mysql://localhost:3306/db-name?useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root

【讨论】:

  • 对,最简单的可能是您的本地 mysql 密码与 application.properties 中配置的密码不同。去检查并更改它。 mw就是这种情况
【解决方案4】:

除了建议的答案,您可以尝试使用 mysql_native_password 身份验证插件而不是 caching_sha2_password 身份验证插件。

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password_here'; 

【讨论】:

    【解决方案5】:

    此解决方案适用于 MacOS Sierra,并运行 MySQL 8.0.11 版。请确保您在构建路径中添加的驱动程序 - “添加外部 jar”应与 SQL 版本匹配。

    String url = "jdbc:mysql://localhost:3306/syscharacterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true";
    

    【讨论】:

      【解决方案6】:

      就我而言,这是用户错误。我正在使用密码无效的root 用户。我不知道为什么我没有收到身份验证错误,而是收到了这条神秘消息。

      【讨论】:

        【解决方案7】:

        在我的情况下,上述错误实际上是由于错误的用户名和密码。 解决问题: 1. 转到 DriverManager.getConnection("jdbc:mysql://localhost:3306/?useSSL=false", "username", "password"); 字段用户名和密码可能是错误的。输入用于启动 mysql 客户端的用户名和密码。用户名一般是root,密码是出现类似这样的画面时输入的字符串Startup screen of mysql

        注意:端口名称 3306 在您的情况下可能会有所不同。

        【讨论】:

          【解决方案8】:

          我发现这个问题令人沮丧,因为我昨天能够与数据库进行交互,但今天早上回来后,我开始收到此错误。

          我尝试添加 allowPublicKeyRetrieval=true 标志,但一直收到错误消息。

          为我解决的问题是在 Eclipse 中执行 Project->Clean 并在我的 Tomcat 服务器上执行 Clean。其中一个(或两个)修复了它。

          我不明白为什么,因为我使用 Maven 构建我的项目,并且在每次代码更改后都重新启动我的服务器。很烦人……

          【讨论】:

            【解决方案9】:

            将连接 URL 指定为 jdbc:mysql://localhost:3306/hb_student_tracker?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC

            【讨论】:

              【解决方案10】:

              如果在连接 mysql(本地或运行 mysql 的 mysql 容器)时遇到以下错误:

              java.sql.SQLNonTransientConnectionException:不允许检索公钥

              解决方案: 在您的数据库服务中添加以下行:

              command: --default-authentication-plugin=mysql_native_password
              

              【讨论】:

                【解决方案11】:

                用mysql更新spring boot应用连接中的useSSL=true;

                jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=true&useLegacyDatetimeCode=false&serverTimezone=UTC
                

                【讨论】:

                  【解决方案12】:

                  DBeaver 用户:

                  1. 右键单击您的连接,选择“编辑连接”

                  2. 在“连接设置”屏幕(主屏幕)上单击“编辑驱动程序设置”

                  3. 点击“连接属性”

                  4. 右键单击“用户属性”区域并选择“添加新属性”

                  5. 添加两个属性:“useSSL”和“allowPublicKeyRetrieval”

                  6. 通过双击“value”列将它们的值设置为“false”和“true”

                  【讨论】:

                  • 对我来说,仅将“驱动程序属性”下的“allowPublicKeyRetrieval”字段从 False 修改为 True 即可。请问为什么要添加“useSSL”属性,然后设置为False? (我也在用 DBeaver)
                  • 在 Ubuntu 16.04 上,我花了很长时间才弄清楚如何设置该值,因为从视觉上看,它没有显示任何看起来像是预期或正在记录的输入。我必须双击 value 列并相信它在按 Enter 或单击它之前正在接受输入,然后我输入的值才会显示出来。
                  • Driver properties 部分/选项卡中设置这两个属性就足够了
                  • 尝试连接到 docker 容器上的开箱即用 mysql 安装。这样做使它工作,所以我可以使用 dbeaver 连接到 mysql 数据库。
                  • 这是我使用 DBeaver 客户端时的正确答案
                  【解决方案13】:

                  在对我们现有的应用程序进行 docker 化时,我也遇到了这样的问题。解决方案是在 JDBC 连接字符串中添加 MySQL 的 allowPublicKeyRetrieval 连接选项,其值为 true。 如果这不起作用,请尝试将 useSSL 选项也添加到 false 中。

                  生成的字符串如下所示:

                  jdbc:mysql://<database server ip>:3306/databaseName?allowPublicKeyRetrieval=true&useSSL=false
                  

                  【讨论】:

                    【解决方案14】:

                    首先,请确保您的数据库服务器已启动并正在运行。 我遇到了同样的错误,在尝试了此处列出的所有答案后,我发现我的数据库服务器没有运行。

                    您可以从 MySQL Workbench 或命令行使用

                    进行检查
                    mysql -u USERNAME -p
                    

                    这听起来很明显,但很多时候我们假设数据库服务器一直在运行,尤其是当我们在本地机器上工作时,当我们重新启动/关闭机器时,数据库服务器会自动关闭。

                    【讨论】:

                    • 我通过终端登录mysql并再次尝试,它成功了。
                    【解决方案15】:

                    这也可能由于用户名或密码错误而发生。 作为解决方案,我添加了allowPublicKeyRetrieval=true&amp;useSSL=false 部分,但仍然出现错误,然后我检查了密码,但它是错误的。

                    【讨论】:

                      【解决方案16】:

                      DBeaver 执行此操作时,我必须转到“连接设置”->“SSL”选项卡,然后:

                      • 取消选中“验证服务器证书”
                      • 选中“允许公钥检索”

                      这就是它的样子。

                      请注意,这仅适用于本地开发。

                      【讨论】:

                      • 这是最新版本的 DB Beaver 对我有用的方法
                      • 太棒了。它适用于 DBeaver 版本 21.0.4
                      • 这解决了我的问题
                      • 这应该是 DBeaver 用户的答案。
                      • 主要的兴趣在于,127.0.0.1:3036 本地普通 SSH 隧道连接似乎甚至需要 SSL 选项。
                      【解决方案17】:

                      Server Time Zone 设置为我的本地位置,解决了问题。


                      【讨论】:

                        【解决方案18】:

                        我的问题出在pom.xml(弹簧靴)。 我的 pom.xml 有两个不同数据库的依赖项。确保只保留 MySQL 依赖项并删除任何其他数据库依赖项。

                        【讨论】:

                          【解决方案19】:

                          另一种方式,在 DBeaver 上。

                          您可以编辑数据库的连接,转到连接设置中的 SSL 选项卡。有一个复选框“允许公钥检索”将其标记为真。这样问题就解决了。

                          【讨论】:

                            【解决方案20】:

                            在 MySQL 8.0 中,默认身份验证插件已从 mysql_native_password 更改为 caching_sha2_password。 有关此更改的更多信息,请参阅https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password

                            这意味着,为了使用 caching_sha2_password 连接必须执行以下操作之一:

                            你有几个选择:

                            • ALTER 用户使用 mysql_native_password 插件(就像它在历史上的表现一样,也可以与不支持 cache_sha2_password 的旧客户端/连接一起使用)
                            • useSSL=true
                            • useSSL=false 并配置公钥检索(这并不意味着使用 allowPublicKeyRetrieval=true 可以避免错误 - 但会破坏这种额外安全性的目标并且速度很慢 - 这确实意味着使用类似 server-public-key 的东西-指向公钥客户端副本的路径)

                            【讨论】:

                              猜你喜欢
                              • 2019-12-16
                              • 2019-07-01
                              • 2014-05-28
                              • 2020-05-29
                              • 1970-01-01
                              • 2019-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2014-01-17
                              相关资源
                              最近更新 更多