5

Java - MySQL: Не разрешено извлечение открытого ключа (Public Key Retrieval)

16

Проблема с подключением к MySQL в Java через Connector 8.0.11

Я пытаюсь подключиться к базе данных MySQL с использованием Java и драйвера Connector 8.0.11. Все выглядит хорошо, но при попытке установить подключение я получаю следующую ошибку:

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)

Вот мой класс ConnectionManager:

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();
    }
}

Может ли кто-нибудь помочь мне разобраться с этой ошибкой? Как я могу разрешить проблему с 'Public Key Retrieval'? Спасибо!

5 ответ(ов)

7

Для пользователей DBeaver:

  1. Щелкните правой кнопкой мыши на вашем подключении и выберите "Изменить подключение".
  2. На экране "Настройки подключения" (основной экран) нажмите на "Изменить параметры драйвера".
  3. Перейдите на вкладку "Параметры драйвера".
  4. Установите следующие два свойства: "allowPublicKeyRetrieval" на true и "useSSL" на false.
0

Чтобы использовать jdbc url, вы можете воспользоваться следующим форматом:

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

Обратите внимание, что PortNo: 3306 может быть другим в вашей конфигурации. Убедитесь, что используете правильный номер порта, который соответствует вашей настройке MySQL.

0

В качестве альтернативы предложенным ответам вы можете попробовать использовать плагин аутентификации mysql_native_password вместо caching_sha2_password. Для этого выполните следующую команду:

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

Не забудьте заменить 'your_password_here' на ваш желаемый пароль. Этот способ может помочь решить проблемы с совместимостью при подключении к вашей базе данных.

0

В 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 соединение должно выполнить одно из следующих условий:

  • использовать защищенное соединение (параметр useSSL=true)
  • использовать незашифрованное соединение, которое поддерживает обмен паролями с использованием ключевой пары RSA (параметры useSSL=false и дополнительные параметры конфигурации - см. https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html)

У вас есть несколько вариантов:

  • Измените пользователей, чтобы использовать плагин mysql_native_password (как это делалось раньше, и это также будет работать со старыми клиентами / соединениями, которые не поддерживают caching_sha2_password).
  • Установите useSSL=true.
  • Установите useSSL=false и настройте получение публичного ключа (это не значит использовать allowPublicKeyRetrieval=true, что могло бы избежать ошибки - но это противоречит цели дополнительной безопасности и медленно; вместо этого используйте что-то вроде server-public-key-path, чтобы указать на копию публичного ключа на стороне клиента).
0

Вы можете вставить следующую строку в ваш файл applications.properties, и это будет означать:

spring.datasource.url=jdbc:mysql://localhost:3306/database?createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useSSL=false
  • spring.datasource.url=jdbc:mysql://localhost:3306/ — здесь используется MySQL как сервис базы данных. Вы можете изменить это на соответствующее имя и порт вашей базы данных.
  • database?createDatabaseIfNotExist=true — используйте базу данных с именем database, если такая база еще не создана, то будет создана новая.
  • allowPublicKeyRetrieval=true — позволяет клиенту автоматически запрашивать открытый ключ с сервера. (Эта часть может быть дополнительной).
  • useSSL=false — отключает SSL и подавляет ошибки SSL.

Кроме того, обратите внимание на свойство spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect в том же файле.

В конце проверьте, добавили ли вы следующую зависимость в файл pom.xml:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.23</version>
</dependency>

Это позволит вашему приложению корректно взаимодействовать с базой данных MySQL.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь