

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# AWS Secrets Manager を使用して認証情報を管理
<a name="manage-credentials-using-aws-secrets-manager"></a>

*Amazon Web Services、Durga Prasad Cheepuri*

## 概要
<a name="manage-credentials-using-aws-secrets-manager-summary"></a>

AWS Secrets Manager を使用して Java Spring アプリケーションのデータベース認証情報を動的に取得します。

以前は、データベースから情報を取得するカスタムアプリケーションを作成する場合は、アプリケーションにデータベースに直接アクセスするための認証情報 (シークレット) を埋め込む必要がありました。認証情報をローテーションする必要がある場合、新しい認証情報を使用するためにアプリケーションを更新し、デプロイするために時間を費やす必要があります。認証情報を共有している複数のアプリケーションがあり、そのうちの 1 つを更新しなかった場合、アプリケーションは中断されます。このリスクのために、多くのお客様は定期的に認証情報を更新せずに、実際のところは代わりに別のリスクを選択していました。

Secrets Manager を使用すると、コード内のハードコードされた認証情報 (パスワードを含む) を、Secrets Manager への API コールで置き換えて、プログラムでシークレットを取得することができます。シークレットはそこに存在しないため､これは、コードを調べている誰かがシークレットを漏らさないようにするのに役立ちます。また、指定したスケジュールに従って自動的にシークレットを更新するように Secrets Manager を設定することができます。これにより、長期のシークレットを短期のシークレットに置き換えることが可能となり、侵害されるリスクが大幅に減少します。詳細については、「[AWS Secrets Manager のドキュメント](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)」を参照してください。

## 前提条件と制限
<a name="manage-credentials-using-aws-secrets-manager-prereqs"></a>

**前提条件**
+ Secrets Manager に対するアクセス権のある AWS アカウント
+ Java Spring アプリケーション

## アーキテクチャ
<a name="manage-credentials-using-aws-secrets-manager-architecture"></a>

**ソーステクノロジースタック**
+ データベースにアクセスするコードを含む Java Spring アプリケーションであり、アプリケーションプロパティファイルから管理されるDB 認証情報も含んでいます。

**ターゲットテクノロジースタック**
+ データベースにアクセスするコードを含む Java Spring アプリケーションであり、Secrets Manager で管理されるDB 認証情報も含んでいます。アプリケーションプロパティファイルには、Secrets Manager のシークレットが格納されています。

Secrets Manager とアプリケーションの統合

![](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/44d359f5-47d9-4228-ac14-a64b5dfa7972/images/fc4b44fd-d1bd-4564-9bc1-c42c896e305b.png)


## ツール
<a name="manage-credentials-using-aws-secrets-manager-tools"></a>
+ **Secrets Manager** — [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) は、シークレットの管理をより簡単にする AWS サービスです。シークレットとは、データベース認証情報、パスワード、サードパーティーの API キーなどの任意のテキストです。Secrets Manager コンソール、Secrets Manager コマンドラインインターフェイス (CLI)、Secrets Manager API および SDK を使用すると、これらのシークレットへのアクセスを一元的に保存および制御できます。

## エピック
<a name="manage-credentials-using-aws-secrets-manager-epics"></a>

### シークレットを Secrets Manager に保存します。
<a name="store-secret-in-secrets-manager"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Secrets Manager で DB 認証情報をシークレットとして保存します。 | Secrets Manager のドキュメントの「[シークレットの作成](https://docs.aws.amazon.com/secretsmanager/latest/userguide/manage_create-basic-secret.html)」の手順に従い、Amazon Relational Database Service (Amazon RDS) またはその他の DB 認証情報をSecrets Manager のシークレットとして保存します。 | Sys Admin | 
| Spring アプリケーションが Secrets Manager にアクセスするための権限を設定します。 | Java Spring アプリケーションが Secrets Manager をどのように使用するかに応じて、適切な権限を設定します。シークレットへのアクセスを制御するには、Secrets Manager のマニュアルに記載されている情報に基づいて、Secrets Managerドキュメントの「[Secrets Manager でアイデンティティベースのポリシー (IAM ポリシー) を使用する](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_identity-based-policies.html)」と「[Secrets Manager のリソースベースのポリシーを使用する](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_resource-based-policies.html)」セクションに記載されている情報に基づいてポリシーを作成します。「Secrets Manager のドキュメント」の「[シークレット値の取得](https://docs.aws.amazon.com/secretsmanager/latest/userguide/manage_retrieve-secret.html)」セクションの手順に従ってください。 | Sys Admin | 

### Spring アプリケーションの更新
<a name="update-the-spring-application"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Secrets Manager を使用するには JAR 依存関係を追加します。 | 詳細については、「*追加情報*」セクションを参照してください。 | Java 開発者 | 
| シークレットの詳細を Spring アプリケーションに追加します。 | アプリケーションプロパティファイルをシークレット名、エンドポイント、AWS リージョンで更新します。例については、「*追加情報*」セクションを参照してください。 | Java 開発者 | 
| Java で DB 認証情報取得コードを更新します。 | アプリケーションで、DB 認証情報を取得する Java コードを更新して Secrets Manager からそれらの詳細を取得します。コードの例については、「*追加情報*」セクションを参照してください。 | Java 開発者 | 

## 関連リソース
<a name="manage-credentials-using-aws-secrets-manager-resources"></a>
+ 「[AWS Secrets Manager のドキュメント](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)」
+ 「[Secrets Manager に対する ID ベースのポリシー (IAM ポリシー) と ABAC の使用](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_identity-based-policies.html)」
+ 「[Secrets Manager のリソースベースのポリシーを使用する](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_resource-based-policies.html)」
+ 「サンプルコード」 

## 追加情報
<a name="manage-credentials-using-aws-secrets-manager-additional"></a>

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'
```

アプリケーションプロパティファイルをシークレット名の詳細で更新

```
spring.aws.secretsmanager.secretName=postgres-local
spring.aws.secretsmanager.endpoint=secretsmanager.us-east-1.amazonaws.com
spring.aws.secretsmanager.region=us-east-1
```

Java で DB 認証情報取得コードの更新

```
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();
}
```