All Products
Search
Document Center

Key Management Service:Secret JDBC client

Last Updated:Aug 15, 2024

In scenarios in which Java Database Connectivity (JDBC) is used to connect to a database, you can store the account of the database in an ApsaraDB RDS secret or a generic secret and then integrate the secret JDBC client into your application. This way, the application can complete identity authentication by using the secret managed by Key Management Service (KMS). This topic describes how to install and use the secret JDBC client.

SDK overview

The secret JDBC client is designed for scenarios in which JDBC is used to connect to databases. The secret JDBC client automatically obtains a secret from KMS to complete identity authentication. In other scenarios in which you want to obtain and use a secret, we recommend that you preferentially use the secret client, followed by KMS Instance SDK and Alibaba Cloud SDK. For more information, see SDK references.

Note

To manage a secret, use Alibaba Cloud SDK.

The secret JDBC client has the following characteristics:

  • Supports JDBC connections, including connections in connection pools such as c3p0 and database connection pool (DBCP) and connections in data sources.

  • Supports ApsaraDB RDS for MySQL, ApsaraDB RDS for SQL Server, ApsaraDB RDS for PostgreSQL, and ApsaraDB RDS for MariaDB.

  • Allows you to specify a custom rotation interval for a secret.

Usage notes

  • Supported secret types: ApsaraDB RDS secret and generic secret.

    • We recommend that you use ApsaraDB RDS secrets in Manage Dual Account mode.

    • The value of a generic secret is in the JSON format. Example:

      {
          "AccountName":"<The username of your database account>",
          "AccountPassword":"<The password of your database account>"
      }
  • Supported programming languages: Java 8 or later.

  • Supported access credentials: AccessKey pair, Resource Access Management (RAM) role, instance RAM role of an Elastic Compute Service (ECS) instance, Security Token Service (STS) token, and client key

Step 1: Create an access credential

Important
  • To obtain the values of secrets that store access credentials such as AccessKey pairs, RAM roles, instance RAM roles of ECS instances, and STS tokens, use a KMS endpoint. To obtain the values of secrets that store client keys, use a KMS endpoint or a KMS instance endpoint. For more information about endpoints, see Endpoint description.

  • KMS instance endpoints supports high performance. We recommend that you use KMS instance endpoints to obtain the values of secrets that store client keys.

AccessKey

For more information, see Create an AccessKey pair.

RAM role

  1. Create a RAM role. For more information, see Create a RAM role.

  2. Obtain RamRoleArn of the RAM role. For more information, see View the information about a RAM role.

    Note

    RamRoleArn is the Alibaba Cloud Resource Name (ARN) of the RAM role, which is the ID of the RAM role to be assumed. Format: acs:ram::$accountID:role/$roleName. $accountID is the ID of the Alibaba Cloud account. $roleName is the name of the RAM role.

Instance RAM role of an ECS instance

Attach an instance RAM role to an ECS instance. For more information, see Grant ECS access to other Alibaba Cloud services by using instance RAM roles.

STS

  1. Create a RAM user or a RAM role. For more information, see Create a RAM user and Create a RAM role.

  2. Grant the AliyunSTSAssumeRoleAccess permission to the RAM user or RAM role. For more information, see Grant permissions to a RAM user and Grant permissions to a RAM role.

  3. Use the RAM user or RAM role to call the AssumeRole operation of STS to obtain an STS token. For more information, see AssumeRole.

ClientKey

Create an application access point (AAP) and then create a client key in the AAP. For more information, see Create an AAP.

Step 2: Install the secret JDBC client

Visit aliyun-secretsmanager-jdbc to view more installation information and source code.

Install the secret JDBC client in your project by using Maven.

<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>
Note

We recommend that you install the latest version.

Step 3: Use the secretsmanager.properties configuration file to configure the runtime parameters of the secret JDBC client

Add the secretsmanager.properties configuration file to the code of your project. The parameters vary based on the access credential that is used.

AccessKey

## The type of the access credential.
credentials_type=ak
## Access Key Id
credentials_access_key_id=#credentials_access_key_id#
## Access Key Secret
credentials_access_secret=#credentials_access_secret#
## The region of the KMS instance.
cache_client_region_id=[{"regionId":"#regionId#"}]
## The custom rotation interval. Default value: 21600000. Minimum value: 300000. Unit: milliseconds. The default value is equivalent to 6 hours, and the minimum value is equivalent to 5 minutes.
refresh_secret_ttl=21600000

RAM role

## The type of the access credential.
credentials_type=ram_role
## Access Key Id
credentials_access_key_id=#credentials_access_key_id#
## Access Key Secret
credentials_access_secret=#credentials_access_secret#
## The name of the session associated with the access credential.
credentials_role_session_name=#credentials_role_session_name#
## RAM Role ARN
credentials_role_arn=#credentials_role_arn#
## The policy for the access credential.
credentials_policy=#credentials_policy#
## The region of the KMS instance.
cache_client_region_id=[{"regionId":"#regionId#"}]
## The custom rotation interval. Default value: 21600000. Minimum value: 300000. Unit: milliseconds. The default value is equivalent to 6 hours, and the minimum value is equivalent to 5 minutes.
refresh_secret_ttl=21600000

Instance RAM role of an ECS instance

## The type of the access credential.
credentials_type=ecs_ram_role
## The name of the instance RAM role that is attached to your ECS instance.
credentials_role_name=#credentials_role_name#
## The region of the KMS instance.
cache_client_region_id=[{"regionId":"#regionId#"}]
## The custom rotation interval. Default value: 21600000. Minimum value: 300000. Unit: milliseconds. The default value is equivalent to 6 hours, and the minimum value is equivalent to 5 minutes.
refresh_secret_ttl=21600000

STS

## The type of the access credential.
credentials_type=sts
## Access Key Id
credentials_access_key_id=#credentials_access_key_id#
## Access Key Secret
credentials_access_secret=#credentials_access_secret#
## The name of the session associated with the access credential.
credentials_role_session_name=#credentials_role_session_name#
## RAM Role ARN
credentials_role_arn=#credentials_role_arn#
## The policy for the access credential.
credentials_policy=#credentials_policy#
## The region of the KMS instance.
cache_client_region_id=[{"regionId":"#regionId#"}]
## The custom rotation interval. Default value: 21600000. Minimum value: 300000. Unit: milliseconds. The default value is equivalent to 6 hours, and the minimum value is equivalent to 5 minutes.
refresh_secret_ttl=21600000

ClientKey

  • KMS endpoint

    ## The type of the access credential.
    credentials_type=client_key
    ## The password for the client key. You can obtain the password from an environment variable or a file.
    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#
    ## The region of the KMS instance.
    cache_client_region_id=[{"regionId":"#regionId#"}]
    ## The custom rotation interval. Default value: 21600000. Minimum value: 300000. Unit: milliseconds. The default value is equivalent to 6 hours, and the minimum value is equivalent to 5 minutes.
    ## In the following configuration, the rotation interval is set to 1 hour.
    refresh_secret_ttl=3600000
    client_key_file_path=#your client key file path# 
  • KMS instance endpoint

    • Method 1: Obtain the password for the client key from a file

      You must save the password to a file. The name of the file must be the same as the value of 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>"}]

      Sample configuration

      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"}]
    • Method 2: Obtain the password for the client key from an environment variable

      You must save the password to an environment variable. The name of the environment variable must be the same as the value of 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>"}]

    Description

    Parameter

    Description

    Setting notes

    regionId

    The ID of the region where the KMS instance resides.

    For more information about how to obtain the region ID, see Regions and endpoints.

    endpoint

    The endpoint of the KMS instance, which is in the {Instance ID}.kms.aliyuncs.com format.

    To view the endpoint of a KMS instance, go to the Instances page in the KMS console, view the details of the KMS instance, obtain the value of Instance VPC Endpoint, and then remove https:// from the value.

    clientKeyFile

    The absolute or relative path to the client key file in the JSON format.

    • Client key file: The file is downloaded when you create a client key for an AAP. The file stores the content of Application Access Secret(ClientKeyContent) and is named in the ClientKey_******.json format.

    • Password file: The file is downloaded when you create a client key for an AAP. The file stores the content of Password and is named in the ClientKey_******_password.txt format.

    Important

    The client key and password have a one-to-one correspondence. You can obtain both only when you create the client key. If you do not save the client key or password when you create the client key, you must create another client key. For more information, see Create an AAP.

    passwordFromFilePath or passwordFromEnvVariable

    • passwordFromFilePath: The password for the client key is obtained from a file. The value is the absolute or relative path to the file that contains the password for the client key. To configure passwordFromFilePath, you must save the password to a file.

    • passwordFromEnvVariable: The password for the client key is obtained from an environment variable. The value is the name of the environment variable that stores the password for the client key. You must save the password to the environment variable.

    ignoreSslCerts

    Specifies whether to ignore the validity check on the SSL certificate of the KMS instance. The KMS instance has a built-in SSL certificate that is used for identity verification and SSL-encrypted or TLS-encrypted communication. Valid values:

    • true: The validity check is ignored.

      Note

      If you set this parameter to true, you do not need to configure caFilePath.

    • false: The validity check is performed.

    In the production environment, set this parameter to false.

    caFilePath

    The absolute or relative path to the certificate authority (CA) certificate file of the KMS instance.

    The CA certificate is used to check the validity of the SSL certificate of the KMS instance. For example, you can check whether the SSL certificate is issued by the required CA, whether the SSL certificate is within the validity period, and whether the domain name bound to the SSL certificate is the endpoint of the KMS instance.

    To obtain the CA certificate, go to the Instances page and click Download below Instance CA Certificate.

Step 4: Use the secret JDBC client to connect to a database

Important

In this example, only the properties that must be modified are provided. You can configure other properties based on your business requirements.

Connect to a database by using JDBC

  • ApsaraDB RDS for MySQL

    Note

    Replace #your-mysql-secret-name#, <your-mysql-ip>, <your-mysql-port>, and <your-database-name> in the sample code with the actual secret name, server IP address of the database, server port number of the database, and name of the database.

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    public class SecretManagerJDBCSample {
        public static void main(String[] args) throws Exception {
            // Load the secret JDBC client.
            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();
            }
        }
    }
  • ApsaraDB RDS for SQL Server

    Note

    Replace #your-sqlserver-secret-name#, <your-sqlserver-ip>, <your-sqlserver-port>, and <your-database-name> in the sample code with the actual secret name, server IP address of the database, server port number of the database, and name of the database.

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    public class SecretManagerJDBCSqlServerSample {
    
        public static void main(String[] args) throws Exception{
            // Load the secret JDBC client.
            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();
            }
        }
    }
  • ApsaraDB RDS for PostgreSQL

    Note

    Replace #your-postgresql-secret-name#, <your-postgresql-ip>, <your-postgresql-port>, and <your-database-name> in the sample code with the actual secret name, server IP address of the database, server port number of the database, and name of the database.

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    public class SecretManagerJDBCPostgreSQLSample {
        public static void main(String[] args) throws Exception {
            // Load the secret JDBC client.
            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();
            }
        }
    }
  • ApsaraDB RDS for MariaDB

    Note

    Replace #your-mariadb-secret-name#, <your-mariadb-ip>, <your-mariadb-port>, and <your-database-name> in the sample code with the actual secret name, server IP address of the database, server port number of the database, and name of the database.

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    public class SecretManagerJDBCMarialDBSample {
    
    	public static void main(String[] args) throws Exception{
    		// Load the secret JDBC client.
    		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();
    		}
    	}
    }

Connect to a database by using a connection pool

Configure c3p0.user, c3p0.driverClass, and c3p0.jdbcUrl in the c3p0 c3p0.properties configuration file. c3p0.user specifies the name of the secret. c3p0.driverClass specifies the name of the secret JDBC driver class. The vale of c3p0.jdbcUrl must start with secrets-manager.

  • ApsaraDB RDS for MySQL

    Note

    Replace #your-mysql-secret-name#, <your-mysql-ip>, <your-mysql-port>, and <your-database-name> in the sample code with the actual secret name, server IP address of the database, server port number of the database, and name of the database.

    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>
  • ApsaraDB RDS for SQL Server

    Note

    Replace #your-sqlserver-secret-name#, <your-sqlserver-ip>, <your-sqlserver-port>, and <your-database-name> in the sample code with the actual secret name, server IP address of the database, server port number of the database, and name of the database.

    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>
  • ApsaraDB RDS for PostgreSQL

    Note

    Replace #your-postgresql-secret-name#, <your-postgresql-ip>, <your-postgresql-port>, and <your-database-name> in the sample code with the actual secret name, server IP address of the database, server port number of the database, and name of the database.

    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>
  • ApsaraDB RDS for MariaDB

    Note

    Replace #your-mariadb-secret-name#, <your-mariadb-ip>, <your-mariadb-port>, and <your-database-name> in the sample code with the actual secret name, server IP address of the database, server port number of the database, and name of the database.

    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>

Connect to a database by using a data source

In this example, c3p0 ComboPooledDataSource and ApsaraDB RDS for MySQL are used. Add the following configuration to the Spring configuration file:

Note

Replace #your-mysql-secret-name#, <your-mysql-ip>, <your-mysql-port>, and <your-database-name> in the sample code with the actual secret name, server IP address of the database, server port number of the database, and name of the database.

<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>
Note

Configure maxPoolSize, minPoolSize, and initialPoolSize based on your business requirements.

Connect to a database by using a Druid connection pool

In this example, ApsaraDB RDS for MySQL is used. You must modify the following properties in the configuration file.

Note

Replace #your-mysql-secret-name#, <your-mysql-ip>, <your-mysql-port>, and <your-database-name> in the sample code with the actual secret name, server IP address of the database, server port number of the database, and name of the database.

  • properties configuration file

    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 configuration mode

    • Method 1: XML configuration file

      <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>
      
    • Method 2: Property injection

      Create a driver class to load database connection information in the application.

      @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;
          }
      }