[英]Disable mySQL RDS client authentication
我正在嘗試從 java SpringBoot 應用程序連接到 mySQL RDS 數據庫。 我已經對數據庫進行了必要的更改。
ALTER USER 'my_app'@'%' require SSL;
GRANT USAGE ON *.* TO 'my_app'@'%' REQUIRE SSL;
但是,連接不會發生。 它在客戶端身份驗證部分失敗。 服務器(mysql db)無法對客戶端(java 應用程序)進行身份驗證。
題:
如何禁用客戶端身份驗證? 根據文檔,除非您執行“REQUIRE X509”,否則應該禁用它。 所以,我對此感到困惑。 我指的文檔是這樣的: https : //dev.mysql.com/doc/refman/8.0/en/alter-user.html 。
我怎樣才能使用 keyStore 和 trustStore 來完成這項工作?
更多信息:
我還將 AWS 根證書和區域證書導入到我的信任存儲中。 此時(沒有作為 JVM 傳遞的 keyStore),連接正常。
但是,在我的應用程序中,我還需要使用 keyStore。
-Djavax.net.ssl.keyStore=path/keyStore.jks
-Djavax.net.ssl.keyStorePassword=<keyStore_password>
當我這樣做時,連接不會發生並拋出以下錯誤:
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
添加 ssl 握手調試我看到以下日志:
*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Cert Authorities:
<Empty>
localhost-startStop-1, READ: TLSv1.1 Handshake, length = 4
*** ServerHelloDone
matching alias: mysqlrds
matching alias: client-nonprod
*** Certificate chain
chain [0] = [
看起來它在服務器(mysql DB)嘗試驗證客戶端(java應用程序)的部分失敗了。 在以下步驟中,客戶端(java 應用程序)需要向服務器(mysql db)提供證書。
在上面的步驟 (CertificateRequest) 中,服務器正在發送一個空的“Cert Authorities”。 這通常意味着服務器(mysql db)有一個空的或未初始化的信任庫。 之后的步驟(證書鏈),客戶端(java app)向服務器(mysql db)發送一個證書。 在這種情況下,“keyStore_cert.jks”。 但是服務器不知道它,它在握手時拋出錯誤。
示例代碼:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
//1. Dowload my sql connector to a folder "jars". http://central.maven.org/maven2/mysql/mysql-connector-java/8.0.13/mysql-connector-java-8.0.13.jar
// This file and the jars folder are on the same folder (or level). Not inside one another.
//2. edit this file to have your settings. Name of the DB,URL,username,password,trustStore,keyStore,DB name, table name.
//3. compile the file: javac -cp ".:./jars/mysql-connector-java-8.0.13.jar" SampleCode.java
//4. run the program: java -cp ".:./jars/mysql-connector-java-8.0.13.jar" SampleCode
public class SampleCode {
public static void main(String[] args) {
Connection con;
try {
// TODO: replace with your settings.
System.setProperty("javax.net.ssl.trustStore", "path/resource/certs/trustStore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "trustStore_pass");
System.setProperty("javax.net.ssl.keyStore", "path/resource/certs/keyStore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "keyStore_pass");
System.setProperty("javax.net.debug", "ssl:handshake");
Class.forName("com.mysql.cj.jdbc.Driver");
// TODO: replace with your settings.
con = DriverManager.getConnection(
"jdbc:mysql://my_db_name.random_string.us-east-1.rds.amazonaws.com:3/my_db?useLegacyDatetimeCode=false&verifyServerCertificate=true&useSSL=true&requireSSL=true",
"my_app", "my_pass");
System.out.println(" connection successful \n");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM my_table "); // TODO: replace with yours.
while (rs.next()) {
System.out.println("id : " + rs.getString("id"));
}
rs.close();
stmt.close();
con.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
參考資料:
我在使用休眠的應用程序中遇到了同樣的錯誤。 顯然 RDS 僅在 SSL 握手期間進行客戶端身份驗證。 您可以通過連接屬性覆蓋用於 jdbc 連接的密鑰庫,而不是禁用客戶端身份驗證,因為您需要為應用程序使用單獨的密鑰庫。
Properties properties = new Properties();
properties.put("user", "my_app");
properties.put("password", "my_pass"); properties.put("clientCertificateKeyStoreUrl","file:path_to_rds_truststore_file");
properties.put("clientCertificateKeyStorePassword","password");
String url = "jdbc:mysql://localhost/mydatabase";
Connection con = DriverManager.getConnection(url, properties);
通過執行上述操作,您可以在使用單獨的系統范圍的密鑰庫時覆蓋將用於建立與 RDS 的連接的密鑰庫。 請注意,每次想要連接到 RDS 實例時都需要設置這些屬性。
正如您的參考文獻中提到的:
請注意,當一起使用時,連接屬性會覆蓋其他兩種方法設置的值。 此外,使用連接屬性設置的任何值僅用於該連接,而使用系統范圍值設置的值用於所有連接(除非被連接屬性覆蓋)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.