การเชื่อมต่อ Java-MySql: ไม่อนุญาตให้เรียกค้นคีย์สาธารณะ


122

ฉันพยายามเชื่อมต่อฐานข้อมูล MySql กับ Java โดยใช้ตัวเชื่อมต่อ 8.0.11 ทุกอย่างดูเหมือนจะโอเค แต่ฉันมีข้อยกเว้นนี้:

ข้อยกเว้นในเธรด "main" java.sql.SQLNonTransientConnectionException: ไม่อนุญาตให้เรียกค้นคีย์สาธารณะ

กองติดตาม:

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

1
โปรดระบุรหัส: คุณกำลังพยายามเชื่อมต่ออย่างไร การติดตามสแต็กของข้อยกเว้นจะเป็นประโยชน์เช่นกัน
จ่าศิริ

คำตอบ:


265

คุณควรเพิ่มตัวเลือกไคลเอนต์ใน mysql-connector ของคุณallowPublicKeyRetrieval=trueเพื่ออนุญาตให้ไคลเอ็นต์ร้องขอคีย์สาธารณะจากเซิร์ฟเวอร์โดยอัตโนมัติ โปรดทราบว่าAllowPublicKeyRetrieval=Trueอาจอนุญาตให้พร็อกซีที่เป็นอันตรายทำการโจมตี MITM เพื่อรับรหัสผ่านข้อความธรรมดาดังนั้นจึงเป็นเท็จโดยค่าเริ่มต้นและต้องเปิดใช้งานอย่างชัดเจน

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

คุณสามารถลองเพิ่ม useSSL=falseเมื่อคุณใช้เพื่อทดสอบ / พัฒนา

ตัวอย่าง:

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

1
สิ่งนี้ใช้ได้ผลสำหรับฉัน แต่ฉันไม่แน่ใจว่าตัวเลือกเหล่านี้มาจากมุมมองด้านความปลอดภัยอย่างถูกต้องอย่างไร
Priyank Thakkar

31
useSSL=false&allowPublicKeyRetrieval=trueคือสิ่งที่ฉันต้องการเฉพาะเมื่อฉันพยายามเชื่อมต่อจากdocker_container1ถึงdocker_container2_mysql(where mysql is installed)ภายในโฮสต์ในพื้นที่ของฉัน ขณะที่จากเครื่องโฮสต์ของฉันไปdocker_container2_mysql, useSSL=falseเป็นพอ
ภาวนา

1
allowPublicKeyRetrieval = true & amp; useSSL = false แทงค์คุณได้ผล
Martin Klestil

2
คุณช่วยอธิบายได้ไหมว่าทำไมถึงเป็นเช่นนี้?
Capn Sparrow

การเพิ่ม 'allowPublicKeyRetrieval = true' ลงในสตริงการเชื่อมต่อ JDBC ของฉันช่วยแก้ปัญหาระบบการพัฒนาของฉันหลังจากอัปเดต Windows 10 เมื่อวานนี้ เดาว่า Microsoft เสียบรูอื่นและควรใช้ตัวเลือก "สำหรับการพัฒนาเท่านั้น" ในมุมมองของฉันโดยที่ SSL ไม่ได้เปิดอยู่
Alz

37

สำหรับผู้ใช้DBeaver :

  1. คลิกขวาที่การเชื่อมต่อของคุณเลือก "แก้ไขการเชื่อมต่อ"

  2. ในหน้าจอ "Connection settings" (หน้าจอหลัก) คลิกที่ "Edit Driver Settings"

  3. คลิกที่ "คุณสมบัติการเชื่อมต่อ"

  4. คลิกขวาที่พื้นที่ "คุณสมบัติของผู้ใช้" แล้วเลือก "เพิ่มคุณสมบัติใหม่"

  5. เพิ่มคุณสมบัติสองอย่าง: "useSSL" และ "allowPublicKeyRetrieval"

  6. ตั้งค่าเป็น "เท็จ" และ "จริง" โดยดับเบิลคลิกที่คอลัมน์ "ค่า"


31

ใช้ jdbc urlเป็น:

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

PortNo: 3306 อาจแตกต่างกันในการกำหนดค่าของคุณ


การแก้ไขเล็กน้อยที่นี่ ค่าคุณสมบัติการเชื่อมต่อ 'useSSL' ที่ยอมรับได้คือ 'TRUE', 'FALSE', 'YES' หรือ 'NO' ค่า 'เท็จ;' ไม่เป็นที่ยอมรับ
bluelurker

12

อีกทางเลือกหนึ่งสำหรับคำตอบที่แนะนำคุณสามารถลองใช้ปลั๊กอินการตรวจสอบสิทธิ์mysql_native_passwordแทนปลั๊กอินการตรวจสอบสิทธิ์caching_sha2_password

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

4

ฉันแก้ปัญหานี้โดยใช้การกำหนดค่าด้านล่างในกรอบสปริงบูต

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

1

ในกรณีของฉันมันเป็นข้อผิดพลาดของผู้ใช้ ฉันใช้rootผู้ใช้ด้วยรหัสผ่านที่ไม่ถูกต้อง ฉันไม่แน่ใจว่าเหตุใดฉันจึงไม่ได้รับข้อผิดพลาดในการตรวจสอบสิทธิ์ แต่กลับได้รับข้อความที่เป็นความลับนี้แทน


1

ข้อผิดพลาดข้างต้นในกรณีของฉันเกิดจากชื่อผู้ใช้และรหัสผ่านไม่ถูกต้อง การแก้ปัญหา: 1. ไปที่บรรทัด DriverManager.getConnection ("jdbc: mysql: // localhost: 3306 /? useSSL = false", "username", "password"); ชื่อผู้ใช้และรหัสผ่านของช่องอาจไม่ถูกต้อง ป้อนชื่อผู้ใช้และรหัสผ่านที่คุณใช้เพื่อเริ่มไคลเอนต์ mysql ชื่อผู้ใช้โดยทั่วไปคือ root และรหัสผ่านคือสตริงที่คุณป้อนเมื่อหน้าจอที่คล้ายกับนี้ปรากฏขึ้นหน้าจอเริ่มต้นของ mysql

หมายเหตุ: ชื่อพอร์ต 3306 อาจแตกต่างกันในกรณีของคุณ


1

ฉันพบว่าปัญหานี้น่าหงุดหงิดเพราะฉันสามารถโต้ตอบกับฐานข้อมูลได้เมื่อวานนี้ แต่หลังจากกลับมาเมื่อเช้านี้ฉันเริ่มได้รับข้อผิดพลาดนี้

ฉันลองเพิ่มไฟล์ allowPublicKeyRetrieval=trueค่าสถานะ แต่ฉันยังคงได้รับข้อผิดพลาด

สิ่งที่แก้ไขสำหรับฉันคือการทำ Project->Cleanใน Eclipse และCleanบนเซิร์ฟเวอร์ Tomcat ของฉัน หนึ่ง (หรือทั้งสองอย่าง) ที่ได้รับการแก้ไข

ฉันไม่เข้าใจว่าเพราะเหตุใดฉันจึงสร้างโครงการโดยใช้ Maven และได้ทำการรีสตาร์ทเซิร์ฟเวอร์ของฉันหลังจากเปลี่ยนรหัสแต่ละครั้ง เคืองมาก ...


1

อัปเดต useSSL = true ในการเชื่อมต่อแอปพลิเคชัน spring boot กับ mysql

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

1

ฉันยังประสบปัญหาดังกล่าวในขณะที่เทียบท่าแอปพลิเคชันที่มีอยู่ของเรา โซลูชันเพื่อเพิ่มอ็อพชันการเชื่อมต่อallowPublicKeyRetrievalของ MySQL ด้วยค่าtrueกับสตริงการเชื่อมต่อ JDBC หากไม่ได้ผลให้ลองเพิ่มตัวเลือกuseSSL เป็น falseเช่นกัน

สตริงผลลัพธ์จะมีลักษณะดังนี้:

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

1

ก่อนอื่นโปรดตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์ฐานข้อมูลของคุณเปิดใช้งานอยู่ ฉันได้รับข้อผิดพลาดเดียวกันหลังจากลองทำตามคำตอบทั้งหมดที่แสดงไว้ที่นี่ฉันพบว่าเซิร์ฟเวอร์ฐานข้อมูลของฉันไม่ทำงาน

คุณสามารถตรวจสอบสิ่งเดียวกันจาก MySQL Workbench หรือ Command line โดยใช้

mysql -u USERNAME -p

ฟังดูชัดเจน แต่หลายครั้งเราคิดว่าเซิร์ฟเวอร์ฐานข้อมูลเปิดใช้งานอยู่ตลอดเวลาโดยเฉพาะอย่างยิ่งเมื่อเราทำงานบนเครื่องท้องถิ่นของเราเมื่อเรารีสตาร์ท / ปิดเครื่องเซิร์ฟเวอร์ฐานข้อมูลจะปิดโดยอัตโนมัติ


0

โซลูชันนี้ใช้ได้กับ MacOS Sierra และใช้งาน MySQL เวอร์ชัน 8.0.11 โปรดตรวจสอบให้แน่ใจว่าคุณได้เพิ่มไดร์เวอร์ใน build path - "add external jar" ควรตรงกับเวอร์ชัน SQL

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

0

ระบุ URL การเชื่อมต่อเป็น jdbc: mysql: // localhost: 3306 / hb_student_tracker? allowPublicKeyRetrieval = true & useSSL = false & serverTimezone = UTC


0

หากคุณได้รับข้อผิดพลาดต่อไปนี้ขณะเชื่อมต่อ mysql (คอนเทนเนอร์ในเครื่องหรือ mysql ที่เรียกใช้ mysql):

java.sql.SQLNonTransientConnectionException: ไม่อนุญาตให้เรียกค้นคีย์สาธารณะ

วิธีแก้ไข: เพิ่มบรรทัดต่อไปนี้ในบริการฐานข้อมูลของคุณ:

command: --default-authentication-plugin=mysql_native_password

0

สิ่งนี้อาจเกิดขึ้นได้เนื่องจากชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง ในฐานะที่เป็นวิธีแก้ปัญหาฉันได้เพิ่ม allowPublicKeyRetrieval=true&useSSL=falseส่วนหนึ่งแล้ว แต่ฉันยังคงพบข้อผิดพลาดจากนั้นฉันตรวจสอบรหัสผ่านและมันผิด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.