針對使用JDBC方式連接數據庫的業務場景,您將數據庫賬號密碼保存在RDS憑據或通用憑據后,應用可以集成憑據JDBC客戶端,通過在KMS托管的憑據完成數據庫連接身份鑒別。本文介紹如何安裝和使用憑據JDBC客戶端。
SDK介紹
憑據JDBC客戶端是針對使用JDBC方式連接數據庫的業務場景,該客戶端自動從KMS獲取憑據用于數據庫連接身份鑒別,更便于您集成。其他獲取和使用憑據的業務場景推薦您優先使用憑據客戶端,其次是KMS實例SDK和阿里云SDK。詳細信息,請參見SDK參考。
如果您需要對憑據進行管控類操作,僅支持使用阿里云SDK。
憑據JDBC客戶端具有以下功能特性:
支持Java數據庫連接(Java Database Connectivity,簡稱JDBC),包括在數據庫連接池(例如c3p0和DBCP)和數據源中通過JDBC連接數據庫。
支持MySQL、SQL Server、PostgreSQL和MariaDB四種數據庫類型。
支持用戶自定義憑據刷新頻率。
注意事項
支持的憑據類型:通用憑據、RDS憑據。
如果是RDS憑據,建議您使用雙賬號托管的RDS憑據。
如果是通用憑據,憑據值為JSON格式且內容格式如下。
{ "AccountName":"<您的數據庫賬號用戶名>", "AccountPassword":"<您的數據庫賬號密碼>" }
支持的開發語言:Java(Java 8及以上版本)。
支持的訪問憑證:AccessKey、RAM角色、ECS RAM角色、STS、ClientKey
步驟一:創建訪問憑證
AccessKey、RAM角色、ECS RAM角色、STS僅支持通過KMS服務Endpoint獲取憑據值,ClientKey既支持通過KMS服務Endpoint,也支持通過KMS實例Endpoint獲取憑據值。關于Endpoint的詳細介紹,請參見Endpoint說明。
KMS實例Endpoint支持更高的性能,因此推薦您使用ClientKey通過KMS實例Endpoint獲取憑據值。
AccessKey
具體操作,請參見創建AccessKey。
RAM角色
ECS RAM角色
為ECS實例授予RAM角色。具體操作,請參見通過ECS實例RAM角色授權ECS訪問其他云服務。
STS
為RAM用戶或RAM角色授予
AliyunSTSAssumeRoleAccess
權限。具體操作,請參見為RAM用戶授權、為RAM角色授權。使用RAM用戶或RAM角色調用STS服務的AssumeRole接口獲取STS臨時訪問憑證。具體操作,請參見AssumeRole - 獲取扮演角色的臨時身份憑證。
ClientKey
您需要先創建應用接入點AAP,然后在AAP中創建ClientKey。具體操作,請參見創建應用接入點。
步驟二:安裝客戶端
訪問aliyun-secretsmanager-jdbc了解更多安裝信息和源代碼。
通過Maven的方式安裝憑據JDBC客戶端。
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-secretsmanager-jdbc</artifactId>
<version>x.x.x</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.x.x</version>
</dependency>
建議您安裝最新版本的SDK。
步驟三:通過配置文件(secretsmanager.properties)設置客戶端運行參數
在項目的運行代碼中新增配置文件secretsmanager.properties,不同訪問憑證需要配置的參數不同。
AccessKey
## 訪問憑據類型
credentials_type=ak
## Access Key Id
credentials_access_key_id=#credentials_access_key_id#
## Access Key Secret
credentials_access_secret=#credentials_access_secret#
## 關聯的KMS服務地域
cache_client_region_id=[{"regionId":"#regionId#"}]
## 用戶自定義的刷新頻率, 默認為6小時,最小值為5分鐘,單位為毫秒
refresh_secret_ttl=21600000
RAM角色
## 訪問憑據類型
credentials_type=ram_role
## Access Key Id
credentials_access_key_id=#credentials_access_key_id#
## Access Key Secret
credentials_access_secret=#credentials_access_secret#
## 訪問憑據Session名稱
credentials_role_session_name=#credentials_role_session_name#
## RAM Role ARN
credentials_role_arn=#credentials_role_arn#
## 訪問憑據Policy
credentials_policy=#credentials_policy#
## 關聯的KMS服務地域
cache_client_region_id=[{"regionId":"#regionId#"}]
## 用戶自定義的刷新頻率, 默認為6小時,最小值為5分鐘,單位為毫秒
refresh_secret_ttl=21600000
ECS實例RAM角色
## 訪問憑據類型
credentials_type=ecs_ram_role
## ECS RAM Role名稱
credentials_role_name=#credentials_role_name#
## 關聯的KMS服務地域
cache_client_region_id=[{"regionId":"#regionId#"}]
## 用戶自定義的刷新頻率, 默認為6小時,最小值為5分鐘,單位為毫秒
refresh_secret_ttl=21600000
STS
## 訪問憑據類型
credentials_type=sts
## Access Key Id
credentials_access_key_id=#credentials_access_key_id#
## Access Key Secret
credentials_access_secret=#credentials_access_secret#
## 訪問憑據Session名稱
credentials_role_session_name=#credentials_role_session_name#
## RAM Role ARN
credentials_role_arn=#credentials_role_arn#
## 訪問憑據Policy
credentials_policy=#credentials_policy#
## 關聯的KMS服務地域
cache_client_region_id=[{"regionId":"#regionId#"}]
## 用戶自定義的刷新頻率, 默認為6小時,最小值為5分鐘,單位為毫秒
refresh_secret_ttl=21600000
ClientKey
訪問KMS服務Endpoint
## 訪問憑據類型 credentials_type=client_key ## 讀取client key的解密密碼:支持從環境變量或者文件讀取 client_key_password_from_env_variable=#your client key private key password environment variable name# client_key_password_from_file_path=#your client key private key password file path# ## 關聯的KMS服務地域 cache_client_region_id=[{"regionId":"#regionId#"}] ## 用戶自定義的刷新頻率, 默認為6小時,最小值為5分鐘,單位為毫秒 ## 下面的配置將憑據刷新頻率設定為1小時 refresh_secret_ttl=3600000 client_key_file_path=#your client key file path#
訪問KMS實例Endpoint
方式一:通過文件獲取ClientKey憑證口令
您還需要將password配置到文件中,文件名稱由您自定義,但需要和
passwordFromFilePath
的取值相同。cache_client_dkms_config_info=[{"regionId":"<your dkms region>","endpoint":"<your dkms endpoint>","passwordFromFilePath":"< your password file path >","clientKeyFile":"<your Client Key file path>","ignoreSslCerts":false,"caFilePath":"<your CA certificate file path>"}]
cache_client_dkms_config_info=[{"regionId":ch-hangzhou","endpoint":"kst-hzz634e67d126u9p9****.cryptoservice.kms.aliyuncs.com","passwordFromFilePath":"C:\RamSecretPlugin\src\main\resources\clientKeyPassword.txt","clientKeyFile":"C:\RamSecretPlugin\src\main\resources\clientKey_KAAP.json","ignoreSslCerts":false,"caFilePath":"C:\RamSecretPlugin\src\main\resources\PrivateKmsCA_kst-hzz634e67d126u9p9****.pem"}]
方式二:通過環境變量獲取ClientKey憑證口令
您還需要將password配置到系統環境變量中,變量名稱由您自定義,但需要和
passwordFromEnvVariable
的取值相同。cache_client_dkms_config_info=[{"regionId":"<your dkms region>","endpoint":"<your dkms endpoint>","passwordFromEnvVariable":"<your_password_env_variable>","clientKeyFile":"<your ClientKey file path>","ignoreSslCerts":false,"caFilePath":"<your CA certificate file path>"}]
各配置項說明:
配置項
配置項含義
說明
regionId
KMS實例所在地域ID。
具體的地域ID,請參見地域和接入地址。
endpoint
KMS實例的域名地址,格式為
{實例ID}.kms.aliyuncs.com
。在控制臺實例管理頁面,單擊目標KMS實例,在實例詳情頁面查看實例VPC地址,將
https://
去掉后即為KMS實例的域名地址。clientKeyFile
ClientKey文件(JSON格式)的絕對路徑或相對路徑。
ClientKey文件:在應用接入點AAP中創建ClientKey時下載的應用身份憑證內容(ClientKeyContent),下載后文件名默認為ClientKey_******.json。
憑證口令:在應用接入點AAP中創建ClientKey時下載的憑證口令(ClientKeyPassword),下載后文件名默認為ClientKey_******_password.txt。
重要ClientKey文件和憑證口令是一一對應的,僅支持您在創建ClientKey時獲取。如果您在創建時未保存,則需要在應用接入點AAP中重新創建ClientKey。更多詳細內容,請參見創建應用接入點。
passwordFromFilePath或passwordFromEnvVariable
passwordFromFilePath:從文件中獲取憑證口令,取值為文件的絕對路徑或相對路徑。您需要將憑證口令保存到文件中。
passwordFromEnvVariable:從環境變量獲取憑證口令,取值為環境變量名稱。您需要將憑證口令配置到環境變量中。
ignoreSslCerts
是否忽略KMS實例SSL證書的有效性檢查。KMS實例內置SSL證書,使用SSL/TLS協議用于身份驗證和加密通信。取值:
true:表示忽略,不檢查KMS實例SSL證書的有效性。
說明取值為true時,無需配置caFilePath。
false:表示驗證,檢查KMS實例SSL證書的有效性。
正式生產環境中,請將該值設置為false。
caFilePath
KMS實例CA證書文件的絕對路徑或相對路徑。
KMS實例CA證書,用于檢查KMS實例SSL證書的有效性。例如:檢查KMS實例SSL證書是否由對應的CA中心簽發、是否在有效期內、以及對應的域名是否為KMS實例的域名地址(endpoint)。
在實例管理頁面,單擊獲取實例CA證書區域的下載,下載KMS實例的CA證書。
步驟四:使用憑據JDBC客戶端連接數據庫
示例中僅介紹必須修改的屬性,其他屬性請您根據實際業務情況進行填寫。
通過JDBC方式連接數據庫
MySQL數據庫
說明請將
#your-mysql-secret-name#
、<your-mysql-ip>
、<your-mysql-port>
、<your-database-name>
替換為您實際使用的憑據名稱、服務器IP地址、端口、數據庫名稱。import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class SecretManagerJDBCSample { public static void main(String[] args) throws Exception { // 加載阿里云憑據JDBC客戶端 Load the JDBC Driver com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver Class.forName("com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver"); Connection connect = null; try { connect = DriverManager.getConnection("secrets-manager:mysql://<your-mysql-ip>:<your-mysql-port>/<your-database-name>", "#your-mysql-secret-name#",""); } catch(SQLException e) { e.printStackTrace(); } } }
SQLServer數據庫
說明請將
#your-sqlserver-secret-name#
、<your-sqlserver-ip>
、<your-sqlserver-port>
、<your-database-name>
替換為您實際使用的憑據名稱、服務器IP地址、端口、數據庫名稱。import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class SecretManagerJDBCSqlServerSample { public static void main(String[] args) throws Exception{ // 加載阿里云憑據JDBC客戶端 Load the JDBC Driver com.aliyun.kms.secretsmanager.MssqlSecretsManagerSimpleDriver Class.forName("com.aliyun.kms.secretsmanager.MssqlSecretsManagerSimpleDriver"); Connection connect = null; try { connect = DriverManager.getConnection("secrets-manager:sqlserver://<your-sqlserver-ip>:<your-sqlserver-port>;databaseName=<your-database-name>", "#your-sqlserver-secret-name#", ""); } catch (SQLException e) { e.printStackTrace(); } } }
PostgreSQL數據庫
說明請將
#your-postgresql-secret-name#
、<your-postgresql-ip>
、<your-postgresql-port>
、<your-database-name>
替換為您實際使用的憑據名稱、服務器IP地址、端口、數據庫名稱。import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class SecretManagerJDBCPostgreSQLSample { public static void main(String[] args) throws Exception { // 加載阿里云憑據JDBC客戶端 Load the JDBC Driver com.aliyun.kms.secretsmanager.PostgreSQLSecretManagerSimpleDriver Class.forName("com.aliyun.kms.secretsmanager.PostgreSQLSecretManagerSimpleDriver"); Connection connect = null; try { connect = DriverManager.getConnection("secrets-manager:postgresql://<your-postgresql-ip>:<your-postgresql-port>/<your-database-name>", "#your-postgresql-secret-name#", ""); } catch (SQLException e) { e.printStackTrace(); } } }
MariaDB數據庫
說明請將
#your-mariadb-secret-name#
、<your-mariadb-ip>
、<your-mariadb-port>
、<your-database-name>
替換為您實際使用的憑據名稱、服務器IP地址、端口、數據庫名稱。import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class SecretManagerJDBCMarialDBSample { public static void main(String[] args) throws Exception{ // 加載阿里云憑據JDBC客戶端 Load the JDBC Driver com.aliyun.kms.secretsmanager.MariaDBSecretManagerSimpleDriver Class.forName("com.aliyun.kms.secretsmanager.MariaDBSecretManagerSimpleDriver"); Connection connect = null; try { connect = DriverManager.getConnection("secrets-manager:mariadb://<your-mariadb-ip>:<your-mariadb-port>/<your-database-name>", "#your-mariadb-secret-name#", ""); } catch (SQLException e) { e.printStackTrace(); } } }
通過數據庫連接池連接數據庫
請按如下方式設置c3p0配置文件(c3p0.properties)中的c3p0.user
、c3p0.driverClass
和c3p0.jdbcUrl
。c3p0.user
為憑據名稱,c3p0.driverClass
為阿里云憑據JDBC Driver類名稱,c3p0.jdbcUrl
需要以secrets-manager
開頭。
MySQL數據庫
說明請將
#your-mysql-secret-name#
、<your-mysql-ip>
、<your-mysql-port>
、<your-database-name>
替換為您實際使用的憑據名稱、服務器IP地址、端口、數據庫名稱。c3p0.user=#your-mysql-secret-name# c3p0.driverClass=com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver c3p0.jdbcUrl=secrets-manager:mysql://<your-mysql-ip>:<your-mysql-port>/<your-database-name>
SQLServer數據庫
說明請將
#your-sqlserver-secret-name#
、<your-sqlserver-ip>
、<your-sqlserver-port>
、<your-database-name>
替換為您實際使用的憑據名稱、服務器IP地址、端口、數據庫名稱。c3p0.user=#your-sqlserver-secret-name# c3p0.driverClass=com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver c3p0.jdbcUrl=secrets-manager:sqlserver://<your-sqlserver-ip>:<your-sqlserver-port>/<your-database-name>
PostgreSQL數據庫
說明請將
#your-postgresql-secret-name#
、<your-postgresql-ip>
、<your-postgresql-port>
、<your-database-name>
替換為您實際使用的憑據名稱、服務器IP地址、端口、數據庫名稱。c3p0.user=#your-postgresql-secret-name# c3p0.driverClass=com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver c3p0.jdbcUrl=secrets-manager:postgresql://<your-postgresql-ip>:<your-postgresql-port>/<your-database-name>
MariaDB數據庫
說明請將
#your-mariadb-secret-name#
、<your-mariadb-ip>
、<your-mariadb-port>
、<your-database-name>
替換為您實際使用的憑據名稱、服務器IP地址、端口、數據庫名稱。c3p0.user=#your-mariadb-secret-name# c3p0.driverClass=com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver c3p0.jdbcUrl=secrets-manager:mariadb://<your-mariadb-ip>:<your-mariadb-port>/<your-database-name>
通過數據源(DataSource)連接數據庫
以使用c3p0 ComboPooledDataSource、MySQL數據庫為例,在Spring配置文件中增加如下配置。
請將#your-mysql-secret-name#
、<your-mysql-ip>
、<your-mysql-port>
、<your-database-name>
替換為您實際使用的憑據名稱、服務器IP地址、端口、數據庫名稱。
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
<property name="driverClass" value="com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver" />
<property name="user" value="#your-mysql-secret-name#" />
<property name="jdbcUrl" value="secrets-manager:mysql://<your-mysql-ip>:<your-mysql-port>/<your-database-name>" />
<property name="maxPoolSize" value="***" />
<property name="minPoolSize" value="***" />
<property name="initialPoolSize" value="***" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
<property name="dataSource" ref="dataSource" />
</bean>
請您根據實際需求設置maxPoolSize、minPoolSize和initialPoolSize參數值。
通過Druid連接池連接數據庫
以MySQL數據庫為例,您需要修改配置文件中的如下屬性。
請將#your-mysql-secret-name#
、<your-mysql-ip>
、<your-mysql-port>
、<your-database-name>
替換為您實際使用的憑據名稱、服務器IP地址、端口、數據庫名稱。
properties配置文件方式
username=#your-mysql-secret-name# driverClassName=com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver url=secrets-manager:mysql://<your-mysql-ip>:<your-mysql-port>/<your-database-name>
bean配置方式
方式一:XML配置文件
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="username" value="${your-mysql-secret-name}" /> <property name="driverClassName" value="com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver" /> <property name="url" value="secrets-manager:mysql://<your-mysql-ip>:<your-mysql-port>/<your-database-name>" /> </bean>
方式二:配置屬性注入
在應用中新建一個加載數據庫連接信息的驅動類。
@Configuration public class DataConfig { @Value("${your-mysql-secret-name}") private String username; @Value("com.aliyun.kms.secretsmanager.MysqlSecretsManagerSimpleDriver") private String driverClassName; @Value("secrets-manager:mysql://<your-mysql-ip>:<your-mysql-port>/<your-database-name>") private String url; @Bean(name = "dataSource",initMethod = "init",destroyMethod = "close") public DruidDataSource dataSource(){ DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setUsername(username); druidDataSource.setDriverClassName(driverClassName); druidDataSource.setUrl(url); return druidDataSource; } }