Java - MySQL: Не разрешено извлечение открытого ключа (Public Key Retrieval)
Проблема с подключением к 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 ответ(ов)
Для пользователей DBeaver:
- Щелкните правой кнопкой мыши на вашем подключении и выберите "Изменить подключение".
- На экране "Настройки подключения" (основной экран) нажмите на "Изменить параметры драйвера".
- Перейдите на вкладку "Параметры драйвера".
- Установите следующие два свойства: "allowPublicKeyRetrieval" на
true
и "useSSL" наfalse
.
Чтобы использовать jdbc url
, вы можете воспользоваться следующим форматом:
jdbc:mysql://localhost:3306/Database_dbName?allowPublicKeyRetrieval=true&useSSL=False;
Обратите внимание, что PortNo: 3306
может быть другим в вашей конфигурации. Убедитесь, что используете правильный номер порта, который соответствует вашей настройке MySQL.
В качестве альтернативы предложенным ответам вы можете попробовать использовать плагин аутентификации mysql_native_password вместо caching_sha2_password. Для этого выполните следующую команду:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password_here';
Не забудьте заменить 'your_password_here'
на ваш желаемый пароль. Этот способ может помочь решить проблемы с совместимостью при подключении к вашей базе данных.
В 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
, чтобы указать на копию публичного ключа на стороне клиента).
Вы можете вставить следующую строку в ваш файл 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.
Как проверить, что в JUnit-тестах выбрасывается определенное исключение?
Можно ли перехватить несколько исключений Java в одном блоке catch?
Mockito: Тестирование void метода, который выбрасывает исключение
Почему возникает UnsupportedOperationException при попытке удалить элемент из списка?
Метод получения должен возвращать 'null' или выбрасывать исключение, если не может вернуть значение? [закрыто]