使用 JDBC 和 Amazon Secrets Manager 密钥中的凭证连接到 SQL 数据库 - Amazon Secrets Manager
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 JDBC 和 Amazon Secrets Manager 密钥中的凭证连接到 SQL 数据库

在 Java 应用程序中,您可以使用 Secrets Manager SQL 连接驱动程序通过存储在 Secrets Manager 中的凭证连接到 MySQL、PostgreSQL、Oracle、MSSQLServer、Db2 和 Redshift 数据库。每个驱动程序都会包装基本 JDBC 驱动程序,因此您可以使用 JDBC 调用来访问数据库。但是,您不必为连接传递用户名和密码,而是提供密钥的 ID。驱动程序将调用 Secrets Manager 来检索密钥值,然后使用密钥中的凭证连接到数据库。驱动程序还将使用 Java 客户端缓存库来缓存凭证,这样未来的连接就不需要调用 Secrets Manager。默认情况下,缓存会每小时刷新一次,此外在轮换密钥时也会刷新。要配置缓存,请参阅SecretCacheConfiguration

您可以从 GitHub 下载源代码。

要使用 Secrets Manager SQL 连接驱动程序:

  • 您的应用程序必须处于 Java 8 或更高版本中。

  • 您的密钥必须为以下之一:

    • 预期 JSON 结构中的数据库密钥。要检查格式,请在 Secrets Manager 控制台中查看密钥并选择 Retrieve secret value(检索密钥值)。或者,在 Amazon CLI 中调用 get-secret-value

    • Amazon RDS 托管密钥。对于此类密钥,必须在建立连接时指定端点和端口。

    • Amazon Redshift 托管密钥。对于此类密钥,必须在建立连接时指定端点和端口。

如果您的数据库复制到其他区域,要连接到另一个区域中的副本数据库,请在创建连接时指定区域端点和端口。您可以在作为额外键值对的密钥中、SSM 参数存储参数或代码配置中存储区域连接信息。

要将驱动程序添加到项目中,请在 Maven 构建文件 pom.xml 中为该驱动程序添加以下依赖项。有关更多信息,请参阅 Maven Central 存储库网站上的 Secrets Manager SQL 连接库

<dependency> <groupId>com.amazonaws.secretsmanager</groupId> <artifactId>aws-secretsmanager-jdbc</artifactId> <version>1.0.12</version> </dependency>

驱动程序使用默认凭证提供程序链。如果您在 Amazon EKS 上运行驱动程序,它可能会获取正在运行的节点的凭证,而不会获取服务账户角色。要解决此问题,请将 com.amazonaws:aws-java-sdk-sts 的版本 1 作为依赖项添加到 Gradle 或 Maven 项目文件。

要在 secretsmanager.properties 文件中设置 Amazon PrivateLink DNS 端点 URL 和区域,请执行以下操作:

drivers.vpcEndpointUrl = endpoint URL drivers.vpcEndpointRegion = endpoint region

要覆盖主区域,请设置 AWS_SECRET_JDBC_REGION 环境变量或对 secretsmanager.properties 文件进行以下更改:

drivers.region = region

所需权限:

  • secretsmanager:DescribeSecret

  • secretsmanager:GetSecretValue

有关更多信息,请参阅 权限参考

建立与数据库的连接

下面的示例演示了如何使用密钥中的凭证和连接信息建立与数据库的连接。建立连接后,您可使用 JDBC 调用来访问数据库。有关更多信息,请参阅 Java 文档网站上的 JDBC 基础知识

MySQL
// Load the JDBC driver Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver" ).newInstance(); // Retrieve the connection info from the secret using the secret ARN String URL = "secretId"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);
PostgreSQL
// Load the JDBC driver Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver" ).newInstance(); // Retrieve the connection info from the secret using the secret ARN String URL = "secretId"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);
Oracle
// Load the JDBC driver Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerOracleDriver" ).newInstance(); // Retrieve the connection info from the secret using the secret ARN String URL = "secretId"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);
MSSQLServer
// Load the JDBC driver Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerMSSQLServerDriver" ).newInstance(); // Retrieve the connection info from the secret using the secret ARN String URL = "secretId"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);
Db2
// Load the JDBC driver Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerDb2Driver" ).newInstance(); // Retrieve the connection info from the secret using the secret ARN String URL = "secretId"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);
Redshift
// Load the JDBC driver Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerRedshiftDriver" ).newInstance(); // Retrieve the connection info from the secret using the secret ARN String URL = "secretId"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);

通过指定端点和端口建立连接

以下示例演示了如何使用密钥中的凭证以及指定的端点和端口建立与数据库的连接。

Amazon RDS 托管密钥不包括数据库的端点和端口。要使用由 Amazon RDS 管理的密钥中的主凭证连接到数据库,请在代码中指定这些凭证。

复制到其他区域的密钥可以降低连接到区域数据库的延迟,但复制的密钥将不包含与源密钥不同的连接信息。每个副本都与源密钥相同。要将区域连接信息存储到密钥中,请添加更多键值对来存储区域的端点和端口信息。

建立连接后,您可使用 JDBC 调用来访问数据库。有关更多信息,请参阅 Java 文档网站上的 JDBC 基础知识

MySQL
// Load the JDBC driver Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver" ).newInstance(); // Set the endpoint and port. You can also retrieve it from a key/value pair in the secret. String URL = "jdbc-secretsmanager:mysql://example.com:3306"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);
PostgreSQL
// Load the JDBC driver Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver" ).newInstance(); // Set the endpoint and port. You can also retrieve it from a key/value pair in the secret. String URL = "jdbc-secretsmanager:postgresql://example.com:5432/database"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);
Oracle
// Load the JDBC driver Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerOracleDriver" ).newInstance(); // Set the endpoint and port. You can also retrieve it from a key/value pair in the secret. String URL = "jdbc-secretsmanager:oracle:thin:@example.com:1521/ORCL"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);
MSSQLServer
// Load the JDBC driver Class.forName( "com.amazonaws.secretsmanager.sql.AWSSecretsManagerMSSQLServerDriver" ).newInstance(); // Set the endpoint and port. You can also retrieve it from a key/value pair in the secret. String URL = "jdbc-secretsmanager:sqlserver://example.com:1433"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);
Db2
// Load the JDBC driver Class.forName( "com.amazonaws.com.amazonaws.secretsmanager.sql.AWSSecretsManagerDb2Driver" ).newInstance(); // Set the endpoint and port. You can also retrieve it from a key/value pair in the secret. String URL = "jdbc-secretsmanager:db2://example.com:50000"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);
Redshift
// Load the JDBC driver Class.forName( "com.amazonaws.com.amazonaws.secretsmanager.sql.AWSSecretsManagerRedshiftDriver" ).newInstance(); // Set the endpoint and port. You can also retrieve it from a key/value pair in the secret. String URL = "jdbc-secretsmanager:redshift://example.com:5439"; // Populate the user property with the secret ARN to retrieve user and password from the secret Properties info = new Properties( ); info.put( "user", "secretId" ); // Establish the connection conn = DriverManager.getConnection(URL, info);

使用 c3p0 连接池建立连接

以下示例演示了如何使用 c3p0.properties 文件建立连接池,该文件使用驱动程序从密钥中检索凭证和连接信息。对于 userjdbcUrl,请输入密钥 ID 以配置连接池。然后,您可以从该池中检索连接,并将这些连接用作任何其他数据库连接。有关更多信息,请参阅 Java 文档网站上的 JDBC 基础知识

有关 c3p0 的更多信息,请参阅 Machinery For Change 网站上的 c3p0

MySQL
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver c3p0.jdbcUrl=secretId
PostgreSQL
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver c3p0.jdbcUrl=secretId
Oracle
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerOracleDriver c3p0.jdbcUrl=secretId
MSSQLServer
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMSSQLServerDriver c3p0.jdbcUrl=secretId
Db2
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerDb2Driver c3p0.jdbcUrl=secretId
Redshift
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerRedshiftDriver c3p0.jdbcUrl=secretId

使用 c3p0 连接池通过指定端点和端口来建立连接

以下示例演示了如何使用 c3p0.properties 文件建立连接池,该文件使用驱动程序通过指定的端点和端口检索密钥中的凭证。然后,您可以从该池中检索连接,并将这些连接用作任何其他数据库连接。有关更多信息,请参阅 Java 文档网站上的 JDBC 基础知识

Amazon RDS 托管密钥不包括数据库的端点和端口。要使用由 Amazon RDS 管理的密钥中的主凭证连接到数据库,请在代码中指定这些凭证。

复制到其他区域的密钥可以降低连接到区域数据库的延迟,但复制的密钥将不包含与源密钥不同的连接信息。每个副本都与源密钥相同。要将区域连接信息存储到密钥中,请添加更多键值对来存储区域的端点和端口信息。

MySQL
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver c3p0.jdbcUrl=jdbc-secretsmanager:mysql://example.com:3306
PostgreSQL
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver c3p0.jdbcUrl=jdbc-secretsmanager:postgresql://example.com:5432/database
Oracle
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerOracleDriver c3p0.jdbcUrl=jdbc-secretsmanager:oracle:thin:@example.com:1521/ORCL
MSSQLServer
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMSSQLServerDriver c3p0.jdbcUrl=jdbc-secretsmanager:sqlserver://example.com:1433
Db2
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerDb2Driver c3p0.jdbcUrl=jdbc-secretsmanager:db2://example.com:50000
Redshift
c3p0.user=secretId c3p0.driverClass=com.amazonaws.secretsmanager.sql.AWSSecretsManagerRedshiftDriver c3p0.jdbcUrl=jdbc-secretsmanager:redshift://example.com:5439