本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用 S AWS ecrets Manager 管理证书
由 Durga Prasad Cheepuri 创作 () AWS
创建者:AWS | 环境:PoC 或试点 | 技术:数据库;安全、身份、合规性 |
AWS服务:S AWS ecr ets Manager |
Summary
此模式将引导你使用 S AWS ecrets Manager 动态获取 Java Spring 应用程序的数据库凭据。
过去,当您创建自定义应用程序以从数据库中检索信息时,通常必须在应用程序中直接嵌入访问数据库所需凭证(密钥)。当需要轮换凭证时,您必须投入时间更新应用程序以使用新的凭证,然后分配更新后的应用程序。如果您有多个应用程序共享凭证,而您错过更新其中一个,则该应用程序将会失效。为应对此类风险,许多用户选择不定期轮换凭证,然而,这种行为实际上会带来新的风险。
Secrets Manager 允许您将代码中的硬编码凭据(包括密码)替换为以编程方式检索密钥的API调用。这有助于确保检查者不会泄露密钥,因为代码中根本不包含密钥。此外,您还可以配置 Secrets Manager 根据您指定的计划自动轮换密钥。这样,您就可以将长期密钥替换为短期密钥,从而显著降低泄露风险。有关更多信息,请参阅 S AWSecrets Manager 文档。
先决条件和限制
先决条件
有权访问 Secrets Manager 的AWS账户
Java Spring 应用程序
架构
源技术堆栈
Java Spring 应用程序,其中包含访问数据库的代码,其数据库凭证由 application.properties 文件管理。
目标技术堆栈
Java Spring 应用程序,其中包含访问数据库的代码,其数据库凭证在 Secrets Manager 中管理。application.properties 文件负责保存 Secrets Manager 的密钥。
Secrets Manager 与应用程序集成
工具
S@@ ecrets M anager — S AWS ecrets Manager 是一项可以让你更轻松地管理密钥的AWS服务。密钥可以是数据库凭证、密码、第三方API密钥,甚至是任意文本。你可以使用 Secrets Manager 控制台、Secrets Manager 命令行界面 (CLI) 或 Secrets Manager 和,集中存储和控制对这些密钥的访问。API SDKs
操作说明
任务 | 描述 | 所需技能 |
---|---|---|
将数据库凭证作为密钥存储在 Secrets Manager 中。 | 按照 Secrets Manager 文档中创建密钥中的步骤将亚马逊关系数据库服务 (AmazonRDS) 或其他数据库凭证作为密钥存储在 Secrets Manager 中。 | 系统管理员 |
为 Spring 应用程序设置访问 Secrets Manager 的权限。 | 根据 Java Spring 应用程序使用 Secrets Manager 的方式设置相应权限。要控制对密钥的访问,请根据 Secrets Manager 文档中提供的信息,在 “使用基于身份的策略(IAM策略)”、“ABAC适用于 Secrets Manager” 和 “为 Secrets Manager 使用基于资源的策略” 部分中提供的信息创建策略。按照 Secrets Manager 文档中检索密钥值部分所述的步骤进行操作。 | 系统管理员 |
任务 | 描述 | 所需技能 |
---|---|---|
添加JAR依赖项以使用 Secrets Manager。 | 有关详细信息,请参阅其他信息部分。 | Java 开发人员 |
将密钥的详细信息添加到 Spring 应用程序。 | 使用密钥名称、端点和AWS区域更新应用程序.properties 文件。有关示例,请参阅其他信息部分。 | Java 开发人员 |
在 Java 中更新数据库凭证检索代码。 | 在应用程序中,更新获取数据库凭证的 Java 代码,以从 Secrets Manager 获取这些详细信息。有关示例代码,请参阅其他信息部分。 | Java 开发人员 |
相关资源
其他信息
为使用 Secrets Manager 添加JAR依赖项
Maven:
<groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-secretsmanager</artifactId> <version>1.11. 355 </version>
Gradle:
compile group: 'com.amazonaws', name: 'aws-java-sdk-secretsmanager', version: '1.11.355'
使用密钥的详细信息更新 application.properties 文件
spring.aws.secretsmanager.secretName=postgres-local spring.aws.secretsmanager.endpoint=secretsmanager.us-east-1.amazonaws.com spring.aws.secretsmanager.region=us-east-1
在 Java 中更新数据库凭证检索代码
String secretName = env.getProperty("spring.aws.secretsmanager.secretName"); String endpoints = env.getProperty("spring.aws.secretsmanager.endpoint"); String AWS Region = env.getProperty("spring.aws.secretsmanager.region"); AwsClientBuilder.EndpointConfiguration config = new AwsClientBuilder.EndpointConfiguration(endpoints, AWS Region); AWSSecretsManagerClientBuilder clientBuilder = AWSSecretsManagerClientBuilder.standard(); clientBuilder.setEndpointConfiguration(config); AWSSecretsManager client = clientBuilder.build(); ObjectMapper objectMapper = new ObjectMapper(); JsonNode secretsJson = null; ByteBuffer binarySecretData; GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest().withSecretId(secretName); GetSecretValueResult getSecretValueResponse = null; try { getSecretValueResponse = client.getSecretValue(getSecretValueRequest); } catch (ResourceNotFoundException e) { log.error("The requested secret " + secretName + " was not found"); } catch (InvalidRequestException e) { log.error("The request was invalid due to: " + e.getMessage()); } catch (InvalidParameterException e) { log.error("The request had invalid params: " + e.getMessage()); } if (getSecretValueResponse == null) { return null; } // Decrypted secret using the associated KMS key // Depending on whether the secret was a string or binary, one of these fields will be populated String secret = getSecretValueResponse.getSecretString(); if (secret != null) { try { secretsJson = objectMapper.readTree(secret); } catch (IOException e) { log.error("Exception while retrieving secret values: " + e.getMessage()); } } else { log.error("The Secret String returned is null"); return null; } String host = secretsJson.get("host").textValue(); String port = secretsJson.get("port").textValue(); String dbname = secretsJson.get("dbname").textValue(); String username = secretsJson.get("username").textValue(); String password = secretsJson.get("password").textValue(); }