使用 AWS Secrets Manager 管理 RDS 访问
Manage RDS access with AWS Secrets Manager
我目前正在使用 Eclipse 和 AWS Toolkit for Eclipse。我的项目已经运行并且正在完成它的工作,即连接到 RDS 实例和 return JSON 对象到 API 网关调用。
我刚接到一个新需求,我们要使用服务 SecretsManager 来自动轮换 RDS 配置,例如用户、密码等。
问题是当我尝试导入 类 例如 GetSecretValueResponse
时,我得到了 The import com.amazonaws.services.secretsmanager cannot be resolved
。当我浏览文档和 SDK 时,存在 GetSecretValueRequest
而不是 GetSecretValueResponse
,所以我无法理解我应该做什么,也没有找到任何类似于示例的东西我可以学习。
下面的代码是我正在尝试实现的,由 Amazon 自己提供(在 Secrets Manager 页面中有一个按钮,您可以单击它来查看它如何与 Java 一起使用,在这种情况下), 它在没有任何修改的情况下呈现,因为正如我所说,我不知道如何导入几个 类:
// Use this code snippet in your app.
public static void getSecret() {
String secretName = "secretName";
String endpoint = "secretEndpoint";
String region = "region";
AwsClientBuilder.EndpointConfiguration config = new AwsClientBuilder.EndpointConfiguration(endpoint, region);
AWSSecretsManagerClientBuilder clientBuilder = AWSSecretsManagerClientBuilder.standard();
clientBuilder.setEndpointConfiguration(config);
AWSSecretsManager client = clientBuilder.build();
String secret;
ByteBuffer binarySecretData;
GetSecretValueRequest getSecretValueRequest = GetSecretValueRequest.builder()
.withSecretId(secretName)
.build();
GetSecretValueResponse getSecretValueResponse = null;
try {
getSecretValueResponse = client.getSecretValue(getSecretValueRequest);
} catch(ResourceNotFoundException e) {
System.out.println("The requested secret " + secretName + " was not found");
} catch (InvalidRequestException e) {
System.out.println("The request was invalid due to: " + e.getMessage());
} catch (InvalidParameterException e) {
System.out.println("The request had invalid params: " + e.getMessage());
}
if(getSecretValueResponse == null) {
return;
}
// Decrypted secret using the associated KMS CMK
// Depending on whether the secret was a string or binary, one of these fields will be populated
if(getSecretValueResponse.getSecretString() != null) {
secret = getSecretValueResponse.getSecretString();
}
else {
binarySecretData = getSecretValueResponse.getSecretBinary();
}
// Your code goes here.
}
我遇到了同样的问题,AWS 页面上的代码无法立即使用。您要查找的 class 是 GetSecretValueResult
这是最新的 java 文档
这里有一段应该有用:
public void printRdsSecret() throws IOException {
String secretName = "mySecretName";
System.out.println("Requesting secret...");
AWSSecretsManager client = AWSSecretsManagerClientBuilder.standard().build();
GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest().withSecretId(secretName);
GetSecretValueResult getSecretValueResult = client.getSecretValue(getSecretValueRequest);
System.out.println("secret retrieved ");
final String secretBinaryString = getSecretValueResult.getSecretString();
final ObjectMapper objectMapper = new ObjectMapper();
final HashMap<String, String> secretMap = objectMapper.readValue(secretBinaryString, HashMap.class);
String url = String.format("jdbc:postgresql://%s:%s/dbName", secretMap.get("host"), secretMap.get("port"));
System.out.println("Secret url = "+url);
System.out.println("Secret username = "+secretMap.get("username"));
System.out.println("Secret password = "+secretMap.get("password"));
}
这是使用 aws-java-sdk-secretsmanager
版本 1.11.337
测试的
只需将库添加到您的 pom 中:
https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-secretsmanager
我认为主要问题是缺少对 AWS SDK v2.
的依赖
在此处添加使用 AWS SDK v2 的代码片段。以防万一有人在找这个。
package com.may.util;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
import software.amazon.awssdk.services.secretsmanager.model.DecryptionFailureException;
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
import software.amazon.awssdk.services.secretsmanager.model.InternalServiceErrorException;
import software.amazon.awssdk.services.secretsmanager.model.InvalidParameterException;
import software.amazon.awssdk.services.secretsmanager.model.InvalidRequestException;
import software.amazon.awssdk.services.secretsmanager.model.ResourceNotFoundException;
public class SecretsManagerUtil {
public static String obtainSecret() {
String secretName = "db_secret_name";
String region = "us-east-1";
SecretsManagerClient client = SecretsManagerClient.builder().region(Region.of(region)).build();
GetSecretValueResponse response = null;
try {
response = client.getSecretValue(GetSecretValueRequest.builder().secretId(secretName).build());
} catch (DecryptionFailureException e) {
// Secrets Manager can't decrypt the protected secret text using the provided KMS key.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (InternalServiceErrorException e) {
// An error occurred on the server side.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (InvalidParameterException e) {
// You provided an invalid value for a parameter.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (InvalidRequestException e) {
// You provided a parameter value that is not valid for the current state of the resource.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (ResourceNotFoundException e) {
// We can't find the resource that you asked for.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
}
return response.secretString();
}
}
反序列化并打印秘密:
public class SecretPrinter {
private static final Logger logger = LoggerFactory.getLogger(SecretPrinter.class);
public void printSecret() {
String json = SecretsManagerUtil.obtainSecret(); // secret in json format
RdsSecret secret;
try {
secret = new ObjectMapper().disable(FAIL_ON_UNKNOWN_PROPERTIES).readValue(json, RdsSecret.class);
} catch (IOException e) {
logger.error("Couldn't parse secret obtained from AWS Secrets Manager!");
throw new RuntimeException(e);
}
System.out.println("username: " + secret.getUsername());
System.out.println("password: " + secret.getPassword());
}
static class RdsSecret {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
}
专家:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.6.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>secretsmanager</artifactId>
</dependency>
Gradle:
implementation platform('software.amazon.awssdk:bom:2.6.3')
implementation 'software.amazon.awssdk:secretsmanager'
我建议使用 aws secret manger jdbc wrapper 来访问 RDS (https://github.com/aws/aws-secretsmanager-jdbc)。在传递给 RDS 客户端之前,您无需处理提取密码、解码和在文本中移动密码的问题。
只需将秘密 ID 传递给 RDS 客户端,jdbc 包装器将处理其余部分。
aws-secretsmanager-jdbc 可用于通过 AWS secret manager 访问 AWS RDS。
https://github.com/aws/aws-secretsmanager-jdbc
下面是我application.properties
的内容
spring.datasource.url=jdbc-secretsmanager:mysql://dev-xxxx-database.cluster-xxxxxxxxx.ap-southeast-1.rds.amazonaws.com:3306/dev_xxxxxx
spring.datasource.username=/secret/application
spring.datasource.driver-class-name=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
下面是AWS secret manager中的secret。
使用此方法,您无需手动获取用户名和密码,也无需创建数据源。
您缺少“aws-java-sdk-secretsmanager”依赖项,您必须将其添加到您的 pom.xml,然后导入到您的 java class。
来自 Maven:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-secretsmanager</artifactId>
<version>1.11.355 </version>
</dependency>
如果你没有使用 maven,你有 add AWS SDK to your existing project.
我目前正在使用 Eclipse 和 AWS Toolkit for Eclipse。我的项目已经运行并且正在完成它的工作,即连接到 RDS 实例和 return JSON 对象到 API 网关调用。
我刚接到一个新需求,我们要使用服务 SecretsManager 来自动轮换 RDS 配置,例如用户、密码等。
问题是当我尝试导入 类 例如 GetSecretValueResponse
时,我得到了 The import com.amazonaws.services.secretsmanager cannot be resolved
。当我浏览文档和 SDK 时,存在 GetSecretValueRequest
而不是 GetSecretValueResponse
,所以我无法理解我应该做什么,也没有找到任何类似于示例的东西我可以学习。
下面的代码是我正在尝试实现的,由 Amazon 自己提供(在 Secrets Manager 页面中有一个按钮,您可以单击它来查看它如何与 Java 一起使用,在这种情况下), 它在没有任何修改的情况下呈现,因为正如我所说,我不知道如何导入几个 类:
// Use this code snippet in your app.
public static void getSecret() {
String secretName = "secretName";
String endpoint = "secretEndpoint";
String region = "region";
AwsClientBuilder.EndpointConfiguration config = new AwsClientBuilder.EndpointConfiguration(endpoint, region);
AWSSecretsManagerClientBuilder clientBuilder = AWSSecretsManagerClientBuilder.standard();
clientBuilder.setEndpointConfiguration(config);
AWSSecretsManager client = clientBuilder.build();
String secret;
ByteBuffer binarySecretData;
GetSecretValueRequest getSecretValueRequest = GetSecretValueRequest.builder()
.withSecretId(secretName)
.build();
GetSecretValueResponse getSecretValueResponse = null;
try {
getSecretValueResponse = client.getSecretValue(getSecretValueRequest);
} catch(ResourceNotFoundException e) {
System.out.println("The requested secret " + secretName + " was not found");
} catch (InvalidRequestException e) {
System.out.println("The request was invalid due to: " + e.getMessage());
} catch (InvalidParameterException e) {
System.out.println("The request had invalid params: " + e.getMessage());
}
if(getSecretValueResponse == null) {
return;
}
// Decrypted secret using the associated KMS CMK
// Depending on whether the secret was a string or binary, one of these fields will be populated
if(getSecretValueResponse.getSecretString() != null) {
secret = getSecretValueResponse.getSecretString();
}
else {
binarySecretData = getSecretValueResponse.getSecretBinary();
}
// Your code goes here.
}
我遇到了同样的问题,AWS 页面上的代码无法立即使用。您要查找的 class 是 GetSecretValueResult
这是最新的 java 文档
这里有一段应该有用:
public void printRdsSecret() throws IOException {
String secretName = "mySecretName";
System.out.println("Requesting secret...");
AWSSecretsManager client = AWSSecretsManagerClientBuilder.standard().build();
GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest().withSecretId(secretName);
GetSecretValueResult getSecretValueResult = client.getSecretValue(getSecretValueRequest);
System.out.println("secret retrieved ");
final String secretBinaryString = getSecretValueResult.getSecretString();
final ObjectMapper objectMapper = new ObjectMapper();
final HashMap<String, String> secretMap = objectMapper.readValue(secretBinaryString, HashMap.class);
String url = String.format("jdbc:postgresql://%s:%s/dbName", secretMap.get("host"), secretMap.get("port"));
System.out.println("Secret url = "+url);
System.out.println("Secret username = "+secretMap.get("username"));
System.out.println("Secret password = "+secretMap.get("password"));
}
这是使用 aws-java-sdk-secretsmanager
版本 1.11.337
只需将库添加到您的 pom 中: https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-secretsmanager
我认为主要问题是缺少对 AWS SDK v2.
的依赖在此处添加使用 AWS SDK v2 的代码片段。以防万一有人在找这个。
package com.may.util;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
import software.amazon.awssdk.services.secretsmanager.model.DecryptionFailureException;
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
import software.amazon.awssdk.services.secretsmanager.model.InternalServiceErrorException;
import software.amazon.awssdk.services.secretsmanager.model.InvalidParameterException;
import software.amazon.awssdk.services.secretsmanager.model.InvalidRequestException;
import software.amazon.awssdk.services.secretsmanager.model.ResourceNotFoundException;
public class SecretsManagerUtil {
public static String obtainSecret() {
String secretName = "db_secret_name";
String region = "us-east-1";
SecretsManagerClient client = SecretsManagerClient.builder().region(Region.of(region)).build();
GetSecretValueResponse response = null;
try {
response = client.getSecretValue(GetSecretValueRequest.builder().secretId(secretName).build());
} catch (DecryptionFailureException e) {
// Secrets Manager can't decrypt the protected secret text using the provided KMS key.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (InternalServiceErrorException e) {
// An error occurred on the server side.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (InvalidParameterException e) {
// You provided an invalid value for a parameter.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (InvalidRequestException e) {
// You provided a parameter value that is not valid for the current state of the resource.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (ResourceNotFoundException e) {
// We can't find the resource that you asked for.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
}
return response.secretString();
}
}
反序列化并打印秘密:
public class SecretPrinter {
private static final Logger logger = LoggerFactory.getLogger(SecretPrinter.class);
public void printSecret() {
String json = SecretsManagerUtil.obtainSecret(); // secret in json format
RdsSecret secret;
try {
secret = new ObjectMapper().disable(FAIL_ON_UNKNOWN_PROPERTIES).readValue(json, RdsSecret.class);
} catch (IOException e) {
logger.error("Couldn't parse secret obtained from AWS Secrets Manager!");
throw new RuntimeException(e);
}
System.out.println("username: " + secret.getUsername());
System.out.println("password: " + secret.getPassword());
}
static class RdsSecret {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
}
专家:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.6.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>secretsmanager</artifactId>
</dependency>
Gradle:
implementation platform('software.amazon.awssdk:bom:2.6.3')
implementation 'software.amazon.awssdk:secretsmanager'
我建议使用 aws secret manger jdbc wrapper 来访问 RDS (https://github.com/aws/aws-secretsmanager-jdbc)。在传递给 RDS 客户端之前,您无需处理提取密码、解码和在文本中移动密码的问题。
只需将秘密 ID 传递给 RDS 客户端,jdbc 包装器将处理其余部分。
aws-secretsmanager-jdbc 可用于通过 AWS secret manager 访问 AWS RDS。 https://github.com/aws/aws-secretsmanager-jdbc
下面是我application.properties
的内容spring.datasource.url=jdbc-secretsmanager:mysql://dev-xxxx-database.cluster-xxxxxxxxx.ap-southeast-1.rds.amazonaws.com:3306/dev_xxxxxx
spring.datasource.username=/secret/application
spring.datasource.driver-class-name=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
下面是AWS secret manager中的secret。
使用此方法,您无需手动获取用户名和密码,也无需创建数据源。
您缺少“aws-java-sdk-secretsmanager”依赖项,您必须将其添加到您的 pom.xml,然后导入到您的 java class。
来自 Maven:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-secretsmanager</artifactId>
<version>1.11.355 </version>
</dependency>
如果你没有使用 maven,你有 add AWS SDK to your existing project.