本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 AWS Secrets Manager 管理登入資料
由杜爾加·普拉薩德·奇普里創作 (AWS)
建立者:AWS | 環境:PoC 或試驗 | 技術:資料庫;安全、身份、合規 |
AWS 服務:AWS Secrets Manager |
Summary
這種模式會引導您使用 AWS Secrets Manager 來動態獲取 Java Spring 應用程序的數據庫憑據。
以往當您建立從資料庫擷取資訊的自訂應用程式時,通常必須內嵌登入資料 (秘密),才可直接存取應用程式中的資料庫。到了輪換登入資料的時間時,您必須花時間將應用程式更新為使用新的登入資料,然後散發更新的應用程式。如果您有多個共用登入資料的應用程式,而您遺漏其中一個的更新,則該應用程式會失敗。因為有此風險,許多使用者選擇不要定期輪換登入資料,但這實際上只是換湯不換藥,風險仍在。
Secrets Manager 可讓您將程式碼中硬式編碼的登入資料 (包括密碼),改成以程式設計方法擷取秘密。這有助於確保您的秘密不會因檢查您的程式碼的人而洩漏,因為秘密根本不在程式碼中。您也可以設定 Secrets Manager,根據您指定的排程自動輪換秘密。這可讓您以短期秘密取代長期秘密,有助於大幅降低洩漏風險。如需詳細資訊,請參閲 。AWS Secrets Manager 文件。
先決條件和限制
先決條件
可存取 Secrets Manager 的 AWS 帳戶
一個 Java 彈簧應用程序
Architecture
來源技術堆疊
Java Spring 應用程序與訪問數據庫的代碼,從應用程序 .properties 文件管理的數據庫憑據。
目標技術堆疊
Java Spring 應用程序與訪問數據庫的代碼,並在秘密管理器中管理數據庫憑據。應用程序 .properties 文件保存秘密管理器的秘密。
Secrets Manager 與應用程序集成

Tools
Secrets Manager–AWS Secrets Manager是可讓您輕鬆管理秘密的 AWS 服務。秘密可能是資料庫登入資料、密碼、第三方 API 金鑰,甚至是任意文字。您可以使用 Secrets Manager 主控台、Secrets Manager 命令列界面 (CLI) 或 Secrets Manager API 和軟體開發套件,以集中存放和控管對這些秘密的存取權。
Epics
任務 | 描述 | 所需技能 |
---|---|---|
將 DB 登入資料存放為 Secrets Manager 中的秘密。 | 將 Amazon Secrets Manager 中的秘密存放為 Secrets Manager 中的秘密,請遵循建立私密在 Secrets Manager 文檔中。 | 系統管理員 |
設置 Spring 應用程序訪問 Secrets Manager 的權限。 | 根據 Java Spring 應用程序如何使用 Secrets Manager 設置適當的權限。若要控制密碼的存取權,請根據「Secrets Manager」文件中提供的資訊建立原則,針對 Secrets Manager 使用以身分為基礎的政策 (IAM 政策) 和 ABAC和對 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'
使用秘密的詳細信息更新應用程序 .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(); }