Connexion Java-MySql: la récupération de clé publique n'est pas autorisée

109

J'essaye de connecter la base de données MySql avec Java en utilisant le connecteur 8.0.11. Tout semble aller bien mais j'ai cette exception:

Exception dans le thread "main" java.sql.SQLNonTransientConnectionException: la récupération de clé publique n'est pas autorisée

Trace de la pile:

    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)

Gestionnaire de connecteurs:

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();
    }
}
Danny
la source
1
Veuillez fournir un code: comment essayez-vous de vous connecter. La trace de la pile de l'exception serait également utile.
Sergei Sirik

Réponses:

240

Vous devez ajouter une option client à votre connecteur mysql allowPublicKeyRetrieval=truepour permettre au client de demander automatiquement la clé publique au serveur. Notez que cela AllowPublicKeyRetrieval=Truepourrait permettre à un proxy malveillant d'effectuer une attaque MITM pour obtenir le mot de passe en clair, il est donc False par défaut et doit être explicitement activé.

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

vous pouvez également essayer d'ajouter useSSL=falselorsque vous l'utilisez à des fins de test / développement

exemple:

jdbc:mysql://localhost:3306/db?allowPublicKeyRetrieval=true&useSSL=false
jtomaszk
la source
1
Eh bien, cela a fonctionné pour moi, mais je ne suis pas sûr de la légitimité de ces options du point de vue de la sécurité.
Priyank Thakkar
29
useSSL=false&allowPublicKeyRetrieval=trueest ce dont j'avais besoin uniquement lorsque j'ai essayé de me connecter de docker_container1à docker_container2_mysql(where mysql is installed)au sein de mon hôte local. Alors que de ma machine hôte à docker_container2_mysql, useSSL=falsec'est suffisant.
priagupd le
1
allowPublicKeyRetrieval = true & amp; useSSL = false, tank you it works
Martin Klestil
2
Pouvez-vous expliquer pourquoi c'est le cas?
Capn Sparrow
L'ajout de 'allowPublicKeyRetrieval = true' à ma chaîne de connexion JDBC a résolu le problème de mon système de développement après une mise à jour de Windows 10 hier. Je suppose que Microsoft a bouché un autre trou, et l'option devrait être utilisée "pour le développement uniquement" à mon avis, là où SSL n'est pas activé.
Alz
30

Utiliser jdbc urlcomme:

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

PortNo: 3306 peut être différent dans votre configuration

susan097
la source
Une petite correction ici. Les valeurs acceptables de la propriété de connexion «useSSL» sont: «TRUE», «FALSE», «YES» ou «NO». La valeur "false;" est inacceptable.
bluelurker
27

Pour les utilisateurs de DBeaver :

  1. Faites un clic droit sur votre connexion, choisissez "Modifier la connexion"

  2. Sur l'écran "Paramètres de connexion" (écran principal), cliquez sur "Modifier les paramètres du pilote"

  3. Cliquez sur "Propriétés de la connexion"

  4. Cliquez avec le bouton droit de la souris sur la zone "Propriétés de l'utilisateur" et choisissez "Ajouter une nouvelle propriété"

  5. Ajoutez deux propriétés: "useSSL" et "allowPublicKeyRetrieval"

  6. Définissez leurs valeurs sur "faux" et "vrai" en double-cliquant sur la colonne "valeur"

Javier Aviles
la source
11

Alternativement aux réponses suggérées, vous pouvez essayer d'utiliser le plugin d'authentification mysql_native_password au lieu du plugin d'authentification caching_sha2_password .

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password_here'; 
Torsten Ojaperv
la source
4

Je résolve ce problème en utilisant la configuration ci-dessous sur le framework 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
shellhub
la source
1

Dans mon cas, c'était une erreur de l'utilisateur. J'utilisais l' rootutilisateur avec un mot de passe invalide. Je ne sais pas pourquoi je n'ai pas eu d'erreur d'authentification, mais j'ai reçu ce message cryptique.

jus
la source
1

L'erreur ci-dessus dans mon cas était en fait due à un nom d'utilisateur et un mot de passe incorrects. Résolution du problème: 1. Accédez à la ligne DriverManager.getConnection ("jdbc: mysql: // localhost: 3306 /? UseSSL = false", "username", "password"); Les champs nom d'utilisateur et mot de passe peuvent être incorrects. Entrez le nom d'utilisateur et le mot de passe que vous utilisez pour démarrer votre client mysql. Le nom d'utilisateur est généralement root et le mot de passe est la chaîne que vous entrez lorsqu'un écran similaire à celui-ci apparaît Écran de démarrage de mysql

Remarque: le nom du port 3306 peut être différent dans votre cas.

hausseStark
la source
1

J'ai trouvé ce problème frustrant car j'ai pu interagir avec la base de données hier, mais après être revenu ce matin, j'ai commencé à recevoir cette erreur.

J'ai essayé d'ajouter le allowPublicKeyRetrieval=truedrapeau, mais j'ai continué à recevoir l'erreur.

Ce qui a résolu le problème pour moi était de faire Project->Cleandans Eclipse et Cleansur mon serveur Tomcat. Un (ou les deux) de ceux-ci l'ont corrigé.

Je ne comprends pas pourquoi, parce que je construis mon projet avec Maven et que j'ai redémarré mon serveur après chaque changement de code. Très irritant ...

Cameron Hudson
la source
1

Mettez à jour useSSL = true dans la connexion de l'application Spring Boot avec mysql;

jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Bheem Singh
la source
1

J'étais également confronté à un tel problème lors de l'ancrage de notre application existante. La solution consiste à ajouter l' option de connexion allowPublicKeyRetrieval de MySQL avec une valeur true à la chaîne de connexion JDBC. Si cela ne fonctionne pas, essayez d'ajouter l' option useSSL à false .

La chaîne résultante ressemblerait à ceci:

jdbc:mysql://<database server ip>:3306/databaseName?allowPublicKeyRetrieval=true&useSSL=false
Arun s
la source
0

Cette solution fonctionnait pour MacOS Sierra et exécutait MySQL version 8.0.11. Veuillez vous assurer que le pilote que vous avez ajouté dans votre chemin de construction - "ajouter un fichier jar externe" doit correspondre à la version SQL.

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

Donnez l'URL de connexion comme jdbc: mysql: // localhost: 3306 / hb_student_tracker? AllowPublicKeyRetrieval = true & useSSL = false & serverTimezone = UTC

samit tiwary
la source
0

Si vous obtenez l'erreur suivante lors de la connexion de mysql (conteneur local ou mysql exécutant le mysql):

java.sql.SQLNonTransientConnectionException: la récupération de clé publique n'est pas autorisée

Solution: ajoutez la ligne suivante dans votre service de base de données:

command: --default-authentication-plugin=mysql_native_password
Rohtash Singh Lakra
la source
0

Tout d'abord, assurez-vous que votre serveur de base de données est opérationnel. J'obtenais la même erreur, après avoir essayé toutes les réponses énumérées ici, j'ai découvert que mon serveur de base de données ne fonctionnait pas.

Vous pouvez vérifier la même chose depuis MySQL Workbench ou la ligne de commande en utilisant

mysql -u USERNAME -p

Cela semble évident, mais nous supposons souvent que le serveur de base de données est opérationnel tout le temps, en particulier lorsque nous travaillons sur notre machine locale, lorsque nous redémarrons / éteignons la machine, le serveur de base de données sera automatiquement arrêté.

Vinod Kumar KV
la source
0

Cela peut également être dû à un nom d'utilisateur ou un mot de passe incorrect. En tant que solutions, j'ai ajouté une allowPublicKeyRetrieval=true&useSSL=falsepartie mais j'ai toujours une erreur, puis j'ai vérifié le mot de passe et c'était faux.

HashanR
la source