java - 如何设置不需要凭据的 Localstack 容器?
问题描述
我有以下代码片段,它应该在 AWS Lambda 函数中运行:
AWSSecretsManager client = AWSSecretsManagerClientBuilder.standard().withRegion(AWS_REGION).build();
GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest().withSecretId(SECRET_NAME);
GetSecretValueResult secretValue = client.getSecretValue(getSecretValueRequest);
由于 lambda 函数将在与秘密管理器相同的 VPC 中运行,因此我不必为其提供凭据 ( AWS_ACCESS_KEY_ID
, AWS_SECRET_ACCESS_KEY
)。
我使用 Localstack 和 Testcontainers 进行集成测试,并在测试设置中设置秘密,如下所示:
AWSSecretsManager secretsManager = AWSSecretsManagerClientBuilder.standard()
.withEndpointConfiguration(secretsmanager.getEndpointConfiguration(SECRETSMANAGER))
.withCredentials(secretsmanager.getDefaultCredentialsProvider())
.build();
String secretString = "{'engine':'mysql','port':" + mysql.getMappedPort(3306) + ",'host':'" + mysql.getContainerIpAddress() + "'}";
CreateSecretRequest request = new CreateSecretRequest().withName("aurora")
.withSecretString(secretString)
.withRequestCredentialsProvider(secretsmanager.getDefaultCredentialsProvider());
secretsManager.createSecret(request);
现在测试因错误而崩溃:
com.amazonaws.services.secretsmanager.model.AWSSecretsManagerException:
The security token included in the request is invalid.
(Service: AWSSecretsManager;
Status Code: 400; Error Code:
UnrecognizedClientException;
Request ID: ...
这里也是测试中使用的localstack容器的定义:
@ClassRule
public static LocalStackContainer secretsmanager = new LocalStackContainer("0.10.4")
.withServices(LocalStackContainer.Service.SECRETSMANAGER)
.withEnv("DEFAULT_REGION", "eu-west-1")
.withExposedPorts(4584);
如何将 LocalStackContainer 配置为在不进行任何凭据验证的情况下接受请求?
解决方案
假设您是一个合理的 java 开发人员,更喜欢 spring boot 测试和 junit5 而不是替代品,@DynamicPropertySource
在这里可以很方便
private static final LocalStackContainer LOCALSTACK = ...;
@DynamicPropertySource
static void setCredentials(DynamicPropertyRegistry registry) {
var credentials = LOCALSTACK.getDefaultCredentialsProvider().getCredentials();
registry.add("cloud.aws.region.static", () -> "eu-central-1");
registry.add("cloud.aws.credentials.access-key", () -> credentials.getAWSAccessKeyId());
registry.add("cloud.aws.credentials.secret-key", () -> credentials.getAWSSecretKey());
registry.add("cloud.aws.s3.endpoint", () -> LOCALSTACK.getEndpointOverride(S3));
}
另外请仔细检查您是否覆盖了您依赖的端点(在我的示例中为 s3),否则您可能会请求真正的 AWS API 而不是容器化的
推荐阅读
- python - 将图像拖到 Kivy 上的目标时消失的图像
- typeclass - 如何证明原始类型类定义之外的类型类的定理?
- c# - 在 C# 中将请求正文转换为数据表或数据集
- javascript - 如何使用 Django URL 在 JavaScript 中传递字符串变量?
- android - 如何在红色文件夹中创建菜单文件夹
- javascript - 不带查询参数、htaccess 或 php 的 URL 重定向
- javascript - 禁用字段集中图例中的复选框未触发
- android - 如何验证已发布的 IOS/Android 应用程序的应用程序开发语言?
- angularjs - AngularJs:将对象设置/获取到 cookie 中
- scala - 如何减少火花中的多个连接