针对使用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及以上版本)。
步骤一:创建访问凭证
场景一:通过共享网关获取凭据值
网络类型为公网或VPC网络。支持ECS实例RAM角色、RamRoleArn、STS Token、AccessKey等基于RAM的身份认证方式。详细内容,请参见管理访问凭据。
ECS实例RAM角色
ECS RAM角色是指为ECS实例授予的RAM角色,该RAM角色是一个受信服务为云服务器的普通服务角色。使用实例RAM角色可以实现在ECS实例内部无需配置AccessKey即可获取临时访问凭证(STS Token),从而调用KMS的OpenAPI。
具体操作,请参见实例RAM角色。
登录RAM控制台,创建可信实体为阿里云服务的RAM角色。
信任主体类型:选择云服务。
信任主体名称:选择云服务器ECS。
授予RAM角色访问KMS的权限。
方式一:设置基于身份的策略
KMS内置了系统权限策略,可以直接绑定到RAM角色,详细介绍,请参见密钥管理服务系统权限策略参考。您也可以自定义权限策略。
方式二:设置基于资源的策略
KMS支持基于资源的策略,即为单个密钥和凭据设置访问权限,用于控制哪些阿里云账号、RAM用户、RAM角色有权限来管理或使用KMS密钥、凭据。详细介绍,请参见密钥策略、凭据策略。
登录ECS管理控制台,将RAM角色授予ECS实例。
RamRoleArn
RAM用户或云产品可以通过扮演角色的方式获取临时权限,而不是直接使用长期密钥,降低了密钥泄露的风险。例如,在临时的数据处理任务中,RAM用户或云产品临时扮演一个具有特定RamRoleArn的角色,完成任务后角色权限被收回,减少泄露风险。
授予RAM角色访问KMS的权限。
方式一:设置基于身份的策略
KMS内置了系统权限策略,可以直接绑定到RAM角色,详细介绍,请参见密钥管理服务系统权限策略参考。您也可以自定义权限策略。
方式二:设置基于资源的策略
KMS支持基于资源的策略,即为单个密钥和凭据设置访问权限,用于控制哪些阿里云账号、RAM用户、RAM角色有权限来管理或使用KMS密钥、凭据。详细介绍,请参见密钥策略、凭据策略。
获取目标RAM角色的RamRoleArn。具体操作,请参见查看RAM角色。
说明RamRoleArn是RAM角色的ARN信息,即需要扮演的角色ID。格式为acs:ram::$accountID:role/$roleName。$accountID为阿里云账号ID。$roleName为RAM角色名称。
STS Token
通过STS服务为RAM用户或RAM角色颁发一个临时访问凭证,可以在限定的有效期内,以符合策略规定的权限访问KMS,超过有效期后,该凭证自动失效。
为RAM用户或RAM角色授予
AliyunSTSAssumeRoleAccess
权限。具体操作,请参见为RAM用户授权、为RAM角色授权。授予RAM用户或RAM角色访问KMS的权限。
方式一:设置基于身份的策略
KMS内置了系统权限策略,可以直接绑定到RAM用户或RAM角色,详细介绍,请参见密钥管理服务系统权限策略参考。您也可以自定义权限策略。
方式二:设置基于资源的策略
KMS支持基于资源的策略,即为单个密钥和凭据设置访问权限,用于控制哪些阿里云账号、RAM用户、RAM角色有权限来管理或使用KMS密钥、凭据。详细介绍,请参见密钥策略、凭据策略。
使用RAM用户或RAM角色调用STS服务的AssumeRole接口获取STS临时访问凭证。具体操作,请参见AssumeRole - 获取扮演角色的临时身份凭证。
AccessKey
以使用RAM用户的AccessKey为例。
阿里云账号默认有所有资源的Administrator权限且不可修改,其AccessKey泄露会危及资源安全,因此强烈建议不要为主账号创建AccessKey,请创建专用于API访问的RAM用户并创建对应的AccessKey,并完成最小化授权。具体操作,请参见创建AccessKey。
登录RAM控制台,在用户页面,单击目标RAM用户名称。
在认证管理页签下的AccessKey区域,单击创建AccessKey,并按照指引完成创建。
授予RAM用户访问KMS的权限。
方式一:设置基于身份的策略
KMS内置了系统权限策略,可以直接绑定到RAM用户,详细介绍,请参见密钥管理服务系统权限策略参考。您也可以自定义权限策略。
方式二:设置基于资源的策略
KMS支持基于资源的策略,即为单个密钥和凭据设置访问权限,用于控制哪些阿里云账号、RAM用户、RAM角色有权限来管理或使用KMS密钥、凭据。详细介绍,请参见密钥策略、凭据策略。
ClientKey(不推荐)
请参考创建应用接入点中的标准创建方式,创建用于访问共享网关的ClientKey。
配置网络规则时,网络类型选择Public或VPC。
配置权限规则作用域时,请选择KMS共享网关。
场景二:通过专属网关获取凭据值(不推荐)
网络类型为KMS私有网络。访问凭证仅支持ClientKey。
ClientKey支持快速创建和标准创建两种方式。关于ClientKey的详细介绍,请参见应用接入点概述、创建应用接入点。
方式一:快速创建
便捷高效适合于快速测试和开发场景,该方式创建的访问凭证可以访问KMS实例的全部资源。
登录密钥管理服务控制台,在顶部菜单栏选择地域后,在左侧导航栏单击 。
在应用接入页签,单击创建应用接入点,在创建应用接入点面板完成各项配置。
配置项
说明
创建模式
选择快速创建。
作用域(KMS实例)
选择应用要访问的KMS实例。
应用接入点名称
自定义应用接入点的名称。
认证方式
默认为ClientKey,不支持修改。
默认权限策略
默认为
key/*
secret/*
,不支持修改。即应用可以访问指定KMS实例中的所有密钥和凭据。单击确定,浏览器会自动下载ClientKey。
ClientKey包含应用身份凭证内容(ClientKeyContent)和凭证口令(ClientKeyPassword)。 应用身份凭证内容(ClientKeyContent)文件名默认为
clientKey_****.json
。凭证口令(ClientKeyPassword)文件名默认为clientKey_****_Password.txt
。
方式二:标准创建
若您希望对资源设置更精细化的访问权限,建议您使用标准创建。具体操作,请参考创建应用接入点。
重要创建应用接入点时如果选择标准创建,需要注意以下两点:
配置网络规则时,网络类型选择Private。
配置权限规则作用域时,请选择对应的KMS实例ID。
步骤二:安装客户端
通过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。访问aliyun-secretsmanager-jdbc了解更多安装信息和源代码。
步骤三:通过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
RAMRoleArn
## 访问凭据类型
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 Token
## 访问凭据类型
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(共享网关)
## 访问凭据类型
credentials_type=client_key
# Client Key文件路径
client_key_private_key_path=#your client key private key file path#
## 读取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
ClientKey(专属网关)
参数配置项为cache_client_dkms_config_info
,cache_client_dkms_config_info
采用JSON数组格式,您可配置多个KMS实例,以支持业务获得更高标准的服务可用性保障和容灾能力。
方式一:通过环境变量获取ClientKey凭证口令
配置文件内容为:
cache_client_dkms_config_info=[{"regionId":"<your dkms regionId >","endpoint":"<your dkms endpoint>","passwordFromEnvVariable":"<YOUR_PASSWORD_ENV_VARIABLE>","clientKeyFile":"<your ClientKey file path>","ignoreSslCerts":false,"caFilePath":"<your CA certificate file path>"}]
该方式您还需要将ClientKey的凭证口令(ClientKeyPassword)的内容配置到环境变量中,变量名称由您自定义,配置完成后将
<YOUR_PASSWORD_ENV_VARIABLE>
替换为变量名称。示例如下:cache_client_dkms_config_info=[{"regionId":"cn-hangzhou","endpoint":"kst-hzz634e67d126u9p9****.cryptoservice.kms.aliyuncs.com","passwordFromEnvVariable":"passwordFromEnvVariable","clientKeyFile":"C:\RamSecretPlugin\src\main\resources\clientKey_KAAP.json","ignoreSslCerts":false,"caFilePath":"C:\RamSecretPlugin\src\main\resources\PrivateKmsCA_kst-hzz634e67d126u9p9****.pem"}]
方式二:通过文件获取ClientKey凭证口令
ClientKey的凭证口令(ClientKeyPassword)下载后文件名默认为
clientKey_****_Password.txt
,您也可以修改文件名称,但需要将cache_client_dkms_config_info取值中<your Client Key file path>
替换为修改后的文件路径。配置文件内容为:
cache_client_dkms_config_info=[{"regionId":"<your dkms regionId >","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":"cn-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"}]
各配置项说明:
配置项 | 配置项含义 | 说明 |
regionId | KMS实例所在地域ID。 | 具体的地域ID,请参见地域和接入地址。 |
endpoint | KMS实例的域名地址,格式为 | 访问实例管理页面,在实例详情页面查看实例VPC地址,即endpoint。 |
clientKeyFile | ClientKey文件(JSON格式)的绝对路径或相对路径。 |
重要 ClientKey文件和凭证口令是一一对应的,仅支持您在创建ClientKey时获取。如果您在创建时未保存,则需要在应用接入点AAP中重新创建ClientKey。更多详细内容,请参见创建应用接入点。 |
passwordFromFilePath或passwordFromEnvVariable |
| |
ignoreSslCerts | 是否忽略KMS实例SSL证书的有效性检查。KMS实例内置SSL证书,使用SSL/TLS协议用于身份验证和加密通信。取值:
| 正式生产环境中,请将该值设置为false。 |
caFilePath | KMS实例CA证书文件的绝对路径或相对路径。 KMS实例CA证书,用于检查KMS实例SSL证书的有效性。例如:检查KMS实例SSL证书是否由对应的CA中心签发、是否在有效期内、以及对应的域名是否为KMS实例的域名地址(endpoint)。 | 访问实例管理页面,在实例详情页面,单击实例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; } }