

# IAM 認証を使用した DB インスタンスへの接続
<a name="UsingWithRDS.IAMDBAuth.Connecting"></a>

IAM データベース認証では、DB インスタンスに接続するときに認証トークンを使用します。*認証トークン*は、パスワードの代わりに使用する文字列です。認証トークンを生成した後、期限切れになるまで 15 分間有効です。期限切れのトークンを使用して接続を試みると、接続リクエストは拒否されます。

すべての認証トークンは、AWS 署名バージョン 4 を使用した有効な署名が添付されている必要があります (詳細については、*AWS 全般のリファレンス*の「[Signature Version 4 の署名プロセス](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)」を参照してください)。AWS CLI や AWS など、AWS SDK for Java とAWS SDK for Python (Boto3) SDK は、作成した各トークンに自動的に署名できます。

別の AWS のサービス (AWS Lambda など) から Amazon RDS に接続するときに、認証トークンを使用できます。トークンを使用することで、コードにパスワードを含めないで済みます。あるいは、AWS SDK を使用して、認証トークンをプログラムで作成して、プログラムで署名することもできます。

IAM 認証トークンに署名した後、Amazon RDS DB インスタンス に接続できます。以下では、コマンドラインツールまたは AWS や AWS SDK for Java などの AWS SDK for Python (Boto3) SDK を使用して、これを行う方法を示しています。

詳細については、以下のブログ投稿を参照してください。
+ [IAM 認証を使用して SQL Workbench/J により Aurora MySQL または Amazon RDS for MySQL に接続する](https://aws.amazon.com/blogs/database/use-iam-authentication-to-connect-with-sql-workbenchj-to-amazon-aurora-mysql-or-amazon-rds-for-mysql/)
+ [pgAdmin Amazon Aurora PostgreSQL または Amazon RDS for PostgreSQL と接続するための IAM 認証の使用](https://aws.amazon.com/blogs/database/using-iam-authentication-to-connect-with-pgadmin-amazon-aurora-postgresql-or-amazon-rds-for-postgresql/)

**前提条件**  
IAM 認証を使用して DB インスタンスに接続するための前提条件は以下のとおりです。
+ [IAM データベース認証の有効化と無効化](UsingWithRDS.IAMDBAuth.Enabling.md)
+ [IAM データベースアクセス用の IAM ポリシーの作成と使用](UsingWithRDS.IAMDBAuth.IAMPolicy.md)
+ [IAM 認証を使用したデータベースアカウントの作成](UsingWithRDS.IAMDBAuth.DBAccounts.md)

**Topics**
+ [IAM 認証と AWS ドライバーを使用した DB インスタンスへの接続](IAMDBAuth.Connecting.Drivers.md)
+ [コマンドラインから IAM 認証を使用して、DB インスタンスに接続する: AWS CLI および mysql クライアント](UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.md)
+ [コマンドラインから IAM 認証を使用して DB インスタンスに接続する: AWS CLI および psql クライアント](UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.PostgreSQL.md)
+ [IAM 認証および AWS SDK for .NET を使用した DB インスタンスへの接続](UsingWithRDS.IAMDBAuth.Connecting.NET.md)
+ [IAM 認証および AWS SDK for Go を使用した DB インスタンスへの接続](UsingWithRDS.IAMDBAuth.Connecting.Go.md)
+ [IAM 認証および AWS SDK for Java を使用した DB インスタンスへの接続](UsingWithRDS.IAMDBAuth.Connecting.Java.md)
+ [IAM 認証および AWS SDK for Python (Boto3) を使用した DB インスタンスへの接続](UsingWithRDS.IAMDBAuth.Connecting.Python.md)

# IAM 認証と AWS ドライバーを使用した DB インスタンスへの接続
<a name="IAMDBAuth.Connecting.Drivers"></a>

AWS のドライバースイートは、スイッチオーバーとフェイルオーバーの時間の短縮、AWS Secrets Manager、AWS Identity and Access Management (IAM)、フェデレーティッド ID での認証をサポートするように設計されています。AWS ドライバーは、DB インスタンスステータスをモニタリングし、インスタンストポロジを認識して新しいライターを決定することを前提としています。このアプローチにより、スイッチオーバーとフェイルオーバーの時間が 1 桁秒に短縮されます (オープンソースドライバーの場合は数十秒)。

AWS ドライバーの詳細については、使用している [RDS for MariaDB](MariaDB.Connecting.Drivers.md#MariaDB.Connecting.JDBCDriver)、[RDS for MySQL](MySQL.Connecting.Drivers.md#MySQL.Connecting.JDBCDriver)、または [RDS for PostgreSQL](PostgreSQL.Connecting.JDBCDriver.md) DB インスタンスに対応する言語ドライバーを参照してください。

**注記**  
RDS for MariaDB でサポートされている機能は、AWS Secrets Manager、AWS Identity and Access Management (IAM)、およびフェデレーティッド ID による認証のみです。

# コマンドラインから IAM 認証を使用して、DB インスタンスに接続する: AWS CLI および mysql クライアント
<a name="UsingWithRDS.IAMDBAuth.Connecting.AWSCLI"></a>

以下に示すように、AWS CLI および `mysql` コマンドラインツールを使用して、コマンドラインから Amazon RDS DB インスタンスに接続できます。

**前提条件**  
IAM 認証を使用して DB インスタンスに接続するための前提条件は以下のとおりです。
+ [IAM データベース認証の有効化と無効化](UsingWithRDS.IAMDBAuth.Enabling.md)
+ [IAM データベースアクセス用の IAM ポリシーの作成と使用](UsingWithRDS.IAMDBAuth.IAMPolicy.md)
+ [IAM 認証を使用したデータベースアカウントの作成](UsingWithRDS.IAMDBAuth.DBAccounts.md)

**注記**  
IAM 認証を使用して SQLWorkbench/J を使用してデータベースに接続する方法については、ブログ記事「[IAM 認証を使用して SQL Workbench/J で Aurora MySQL または Amazon RDS for MySQL に接続する](https://aws.amazon.com/blogs/database/use-iam-authentication-to-connect-with-sql-workbenchj-to-amazon-aurora-mysql-or-amazon-rds-for-mysql/)」を参照してください。

**Topics**
+ [IAM 認証トークンの生成](#UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.AuthToken)
+ [DB インスタンスへの接続](#UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.Connect)

## IAM 認証トークンの生成
<a name="UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.AuthToken"></a>

次の例では、AWS CLI を使用して署名された認証トークンを取得する方法を示します。

```
aws rds generate-db-auth-token \
   --hostname rdsmysql.123456789012.us-west-2.rds.amazonaws.com \
   --port 3306 \
   --region us-west-2 \
   --username jane_doe
```

この例で、パラメータは次のとおりです。
+ `--hostname` - アクセス先の DB インスタンスのホスト名。
+ `--port` - DB インスタンスへの接続に使用するポート番号
+ `--region` - DB インスタンスが実行中の AWS リージョン
+ `--username` - アクセス先のデータベースアカウント

トークンの初期の複数の文字は次のようになります。

```
rdsmysql.123456789012.us-west-2.rds.amazonaws.com:3306/?Action=connect&DBUser=jane_doe&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900...
```

**注記**  
DB インスタンス エンドポイントの代わりに、カスタム Route 53 DNS レコードを使用して認証トークンを生成することはできません。

## DB インスタンスへの接続
<a name="UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.Connect"></a>

接続の全般的な形式を次に示します。

```
mysql --host=hostName --port=portNumber --ssl-ca=full_path_to_ssl_certificate --enable-cleartext-plugin --user=userName --password=authToken
```

パラメータは次のとおりです。
+ `--host` - アクセス先の DB インスタンスのホスト名。
+ `--port` - DB インスタンスへの接続に使用するポート番号
+ `--ssl-ca` - 公開キーを含む SSL 証明書ファイルへのフルパス

  MariaDB での SSL/TLS サポートについては、「[Amazon RDS 上の MariaDB DB インスタンスの SSL/TLS サポート](MariaDB.Concepts.SSLSupport.md)」を参照してください。

  MySQL での SSL/TLS サポートについては、「[Amazon RDS 上の MySQL DB インスタンスの SSL/TLS サポート](MySQL.Concepts.SSLSupport.md)」を参照してください。

  SSL 証明書をダウンロードするには [SSL/TLS を使用した DB インスタンスまたはクラスターへの接続の暗号化](UsingWithRDS.SSL.md) を参照ください。
+ `--enable-cleartext-plugin` - この接続で `AWSAuthenticationPlugin` を使用する必要があることを示す値

  MariaDB クライアントを使用している場合、`--enable-cleartext-plugin` オプションは必須ではありません。
+ `--user` - アクセス先のデータベースアカウント
+ `--password` - 署名済みの IAM 認証トークン

認証トークンは数百の文字で構成されます。これは、コマンドラインでは手に負えなくなる可能性があります。この問題を回避する 1 つの方法は、環境可変にトークンを保存し、接続時にその可変を使用することです。次の例は、この回避策を実行する 1 つの方法を示しています。この例では、*/sample\$1dir/* が公開キーを含む SSL 証明書ファイルへのフルパスです。

```
RDSHOST="mysqldb.123456789012.us-east-1.rds.amazonaws.com"
TOKEN="$(aws rds generate-db-auth-token --hostname $RDSHOST --port 3306 --region us-west-2 --username jane_doe )"

mysql --host=$RDSHOST --port=3306 --ssl-ca=/sample_dir/global-bundle.pem --enable-cleartext-plugin --user=jane_doe --password=$TOKEN
```

`AWSAuthenticationPlugin` を使って接続した場合、接続は SSL を使用して保護されます。これを確認するには、`mysql>` コマンドプロンプトで以下を入力します。

```
show status like 'Ssl%';
```

出力の次の行に詳細情報が示されます。

```
+---------------+-------------+
| Variable_name | Value                                                                                                                                                                                                                                |
+---------------+-------------+
| ...           | ...
| Ssl_cipher    | AES256-SHA                                                                                                                                                                                                                           |
| ...           | ...
| Ssl_version   | TLSv1.1                                                                                                                                                                                                                              |
| ...           | ...
+-----------------------------+
```

プロキシ経由で DB インスタンスに接続する場合は、「[IAM 認証を使用したデータベースへの接続](rds-proxy-connecting.md#rds-proxy-connecting-iam)」を参照してください。

# コマンドラインから IAM 認証を使用して DB インスタンスに接続する: AWS CLI および psql クライアント
<a name="UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.PostgreSQL"></a>

以下に示すように、AWS CLI および psql コマンドラインツールを使用して、コマンドラインから Amazon RDS for PostgreSQL DB インスタンスに接続できます。

**前提条件**  
IAM 認証を使用して DB インスタンスに接続するための前提条件は以下のとおりです。
+ [IAM データベース認証の有効化と無効化](UsingWithRDS.IAMDBAuth.Enabling.md)
+ [IAM データベースアクセス用の IAM ポリシーの作成と使用](UsingWithRDS.IAMDBAuth.IAMPolicy.md)
+ [IAM 認証を使用したデータベースアカウントの作成](UsingWithRDS.IAMDBAuth.DBAccounts.md)

**注記**  
pgAdminを使用してIAM認証でデータベースに接続する方法については、ブログ記事[IAM認証を使用してpgAdmin Amazon Aurora PostgreSQLまたはAmazon RDS for PostgreSQLで接続する](https://aws.amazon.com/blogs/database/using-iam-authentication-to-connect-with-pgadmin-amazon-aurora-postgresql-or-amazon-rds-for-postgresql/)を参照してください。

**Topics**
+ [IAM 認証トークンの生成](#UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.AuthToken.PostgreSQL)
+ [Amazon RDS PostgreSQL インスタンスへの接続](#UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.Connect.PostgreSQL)

## IAM 認証トークンの生成
<a name="UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.AuthToken.PostgreSQL"></a>

認証トークンは数百の文字で構成されるため、コマンドラインでは手に負えなくなる可能性があります。この問題を回避する 1 つの方法は、環境可変にトークンを保存し、接続時にその可変を使用することです。次の例では、AWS CLI コマンドを使用して署名された認証トークンを取得するために `generate-db-auth-token` を使用し、`PGPASSWORD` 環境可変に格納する方法を示しています。

```
export RDSHOST="rdspostgres.123456789012.us-west-2.rds.amazonaws.com"
export PGPASSWORD="$(aws rds generate-db-auth-token --hostname $RDSHOST --port 5432 --region us-west-2 --username jane_doe )"
```

例では、`generate-db-auth-token` コマンドへのパラメータは次のとおりです。
+ `--hostname` - アクセス先の DB インスタンス のホスト名
+ `--port` - DB インスタンスへの接続に使用するポート番号
+ `--region` - DB インスタンスが実行中の AWS リージョン
+ `--username` - アクセス先のデータベースアカウント

生成されたトークンの初期の複数の文字は次のようになります。

```
rdspostgres.123456789012.us-west-2.rds.amazonaws.com:5432/?Action=connect&DBUser=jane_doe&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900...
```

**注記**  
DB インスタンス エンドポイントの代わりに、カスタム Route 53 DNS レコードを使用して認証トークンを生成することはできません。

## Amazon RDS PostgreSQL インスタンスへの接続
<a name="UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.Connect.PostgreSQL"></a>

psql を使用して接続する全般的な形式を次に示します。

```
psql "host=hostName port=portNumber sslmode=verify-full sslrootcert=full_path_to_ssl_certificate dbname=DBName user=userName password=authToken"
```

パラメータは次のとおりです。
+ `host` - アクセス先の DB インスタンス のホスト名
+ `port` - DB インスタンスへの接続に使用するポート番号
+ `sslmode` - 使用する SSL モード

  `sslmode=verify-full` を使用すると、SSL 接続で DB インスタンスのエンドポイントを SSL 証明書のエンドポイントと照合します。
+ `sslrootcert` －公開キーを含む SSL 証明書ファイルへのフルパス

  詳細については、「[PostgreSQL DB インスタンスで SSL を使用する](PostgreSQL.Concepts.General.SSL.md)」を参照してください。

  SSL 証明書をダウンロードするには [SSL/TLS を使用した DB インスタンスまたはクラスターへの接続の暗号化](UsingWithRDS.SSL.md) を参照ください。
+ `dbname` - アクセス先のデータベース
+ `user` - アクセス先のデータベースアカウント
+ `password` - 署名済みの IAM 認証トークン

**注記**  
DB インスタンス エンドポイントの代わりに、カスタム Route 53 DNS レコードを使用して認証トークンを生成することはできません。

次の例は、psql を使用して接続する方法を示しています。この例の psql では、環境変数 `RDSHOST` をホスト用に、また、環境変数 `PGPASSWORD` を生成されたトークン用に使用しています。また、*/sample\$1dir/* は公開キーを含む SSL 証明書ファイルへの完全なパスを示します。

```
export RDSHOST="rdspostgres.123456789012.us-west-2.rds.amazonaws.com"
export PGPASSWORD="$(aws rds generate-db-auth-token --hostname $RDSHOST --port 5432 --region us-west-2 --username jane_doe )"
                    
psql "host=$RDSHOST port=5432 sslmode=verify-full sslrootcert=/sample_dir/global-bundle.pem dbname=DBName user=jane_doe password=$PGPASSWORD"
```

プロキシ経由で DB インスタンスに接続する場合は、「[IAM 認証を使用したデータベースへの接続](rds-proxy-connecting.md#rds-proxy-connecting-iam)」を参照してください。

# IAM 認証および AWS SDK for .NET を使用した DB インスタンスへの接続
<a name="UsingWithRDS.IAMDBAuth.Connecting.NET"></a>

次に説明するように、AWS SDK for .NET を使用して、RDS for MariaDB、MySQL、または PostgreSQL DB インスタンスに接続できます。

**前提条件**  
IAM 認証を使用して DB インスタンスに接続するための前提条件は以下のとおりです。
+ [IAM データベース認証の有効化と無効化](UsingWithRDS.IAMDBAuth.Enabling.md)
+ [IAM データベースアクセス用の IAM ポリシーの作成と使用](UsingWithRDS.IAMDBAuth.IAMPolicy.md)
+ [IAM 認証を使用したデータベースアカウントの作成](UsingWithRDS.IAMDBAuth.DBAccounts.md)

**例**  
以下のコード例で、認証トークンを生成し、それを使用して DB インスタンスに接続する方法を示します。

このコードサンプルを実行するには、AWS SDK for .NET サイトにある [AWS](https://aws.amazon.com/sdk-for-net/) が必要です。`AWSSDK.CORE` および `AWSSDK.RDS` パッケージが必要です。DB インスタンスに接続するには、MariaDB または MySQL 用の MySqlConnector や PostgreSQL 用の Npgsql など、DB エンジン用の .NET データベースコネクタを使用します。

このコードで MariaDB インスタンスまたは MySQL DB インスタンスに接続します。必要に応じて以下の可変の値を変更します。
+ `server` - アクセス先の DB インスタンスのエンドポイント
+ `user` - アクセス先のデータベースアカウント
+ `database` - アクセス先のデータベース
+ `port` - DB インスタンスへの接続に使用するポート番号
+ `SslMode` - 使用する SSL モード

  `SslMode=Required` を使用すると、SSL 接続で DB インスタンスのエンドポイントを SSL 証明書のエンドポイントと照合します。
+ `SslCa` － Amazon RDS のSSL 証明書へのフルパス

  証明書をダウンロードするには、「[SSL/TLS を使用した DB インスタンスまたはクラスターへの接続の暗号化](UsingWithRDS.SSL.md)」を参照してください。

**注記**  
DB インスタンス エンドポイントの代わりに、カスタム Route 53 DNS レコードを使用して認証トークンを生成することはできません。

```
using System;
using System.Data;
using MySql.Data;
using MySql.Data.MySqlClient;
using Amazon;

namespace ubuntu
{
  class Program
  {
    static void Main(string[] args)
    {
      var pwd = Amazon.RDS.Util.RDSAuthTokenGenerator.GenerateAuthToken(RegionEndpoint.USEast1, "mysqldb.123456789012.us-east-1.rds.amazonaws.com", 3306, "jane_doe");
      // for debug only Console.Write("{0}\n", pwd);  //this verifies the token is generated

      MySqlConnection conn = new MySqlConnection($"server=mysqldb.123456789012.us-east-1.rds.amazonaws.com;user=jane_doe;database=mydB;port=3306;password={pwd};SslMode=Required;SslCa=full_path_to_ssl_certificate");
      conn.Open();

      // Define a query
      MySqlCommand sampleCommand = new MySqlCommand("SHOW DATABASES;", conn);

      // Execute a query
      MySqlDataReader mysqlDataRdr = sampleCommand.ExecuteReader();

      // Read all rows and output the first column in each row
      while (mysqlDataRdr.Read())
        Console.WriteLine(mysqlDataRdr[0]);

      mysqlDataRdr.Close();
      // Close connection
      conn.Close();
    }
  }
}
```

このコードで PostgreSQL DB インスタンスに接続します。

必要に応じて以下の可変の値を変更します。
+ `Server` - アクセス先の DB インスタンスのエンドポイント
+ `User ID` - アクセス先のデータベースアカウント
+ `Database` - アクセス先のデータベース
+ `Port` - DB インスタンスへの接続に使用するポート番号
+ `SSL Mode` - 使用する SSL モード

  `SSL Mode=Required` を使用すると、SSL 接続で DB インスタンスのエンドポイントを SSL 証明書のエンドポイントと照合します。
+ `Root Certificate` － Amazon RDS のSSL 証明書へのフルパス

  証明書をダウンロードするには、「[SSL/TLS を使用した DB インスタンスまたはクラスターへの接続の暗号化](UsingWithRDS.SSL.md)」を参照してください。

**注記**  
DB インスタンス エンドポイントの代わりに、カスタム Route 53 DNS レコードを使用して認証トークンを生成することはできません。

```
using System;
using Npgsql;
using Amazon.RDS.Util;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var pwd = RDSAuthTokenGenerator.GenerateAuthToken("postgresmydb.123456789012.us-east-1.rds.amazonaws.com", 5432, "jane_doe");
// for debug only Console.Write("{0}\n", pwd);  //this verifies the token is generated

            NpgsqlConnection conn = new NpgsqlConnection($"Server=postgresmydb.123456789012.us-east-1.rds.amazonaws.com;User Id=jane_doe;Password={pwd};Database=mydb;SSL Mode=Require;Root Certificate=full_path_to_ssl_certificate");
            conn.Open();

            // Define a query
                   NpgsqlCommand cmd = new NpgsqlCommand("select count(*) FROM pg_user", conn);

            // Execute a query
            NpgsqlDataReader dr = cmd.ExecuteReader();

            // Read all rows and output the first column in each row
            while (dr.Read())
                Console.Write("{0}\n", dr[0]);

            // Close connection
            conn.Close();
        }
    }
}
```

プロキシ経由で DB インスタンスに接続する場合は、「[IAM 認証を使用したデータベースへの接続](rds-proxy-connecting.md#rds-proxy-connecting-iam)」を参照してください。

# IAM 認証および AWS SDK for Go を使用した DB インスタンスへの接続
<a name="UsingWithRDS.IAMDBAuth.Connecting.Go"></a>

次に説明するように、AWS SDK for Go を使用して、RDS for MariaDB、MySQL、または PostgreSQL DB インスタンスに接続できます。

**前提条件**  
IAM 認証を使用して DB インスタンスに接続するための前提条件は以下のとおりです。
+ [IAM データベース認証の有効化と無効化](UsingWithRDS.IAMDBAuth.Enabling.md)
+ [IAM データベースアクセス用の IAM ポリシーの作成と使用](UsingWithRDS.IAMDBAuth.IAMPolicy.md)
+ [IAM 認証を使用したデータベースアカウントの作成](UsingWithRDS.IAMDBAuth.DBAccounts.md)

**例**  
これらのコードサンプルを実行するには、AWS SDK for Go サイトにある [AWS](https://aws.amazon.com/sdk-for-go/) が必要です。

必要に応じて以下の可変の値を変更します。
+ `dbName` - アクセス先のデータベース
+ `dbUser` - アクセス先のデータベースアカウント
+ `dbHost` - アクセス先の DB インスタンスのエンドポイント
**注記**  
DB インスタンス エンドポイントの代わりに、カスタム Route 53 DNS レコードを使用して認証トークンを生成することはできません。
+ `dbPort` - DB インスタンスへの接続に使用するポート番号
+ `region` - DB インスタンスが実行中の AWS リージョン

さらに、サンプルコード内のインポートされるライブラリがシステムに存在することを確認してください。

**重要**  
このセクションの例では、次のコードを使用して、ローカル環境からデータベースにアクセスする認証情報を提供します。  
`creds := credentials.NewEnvCredentials()`  
Amazon EC2 や Amazon ECS などの AWS のサービスからデータベースにアクセスする場合は、コードを次のコードに置き換えることができます。  
`sess := session.Must(session.NewSession())`  
`creds := sess.Config.Credentials`  
この変更を行う場合は、次のインポートを追加してください。  
`"github.com/aws/aws-sdk-go/aws/session"`

**Topics**
+ [IAM 認証と AWS SDK for Go V2 を使用した接続](#UsingWithRDS.IAMDBAuth.Connecting.GoV2)
+ [IAM 認証と AWS SDK for Go V1 を使用した接続。](#UsingWithRDS.IAMDBAuth.Connecting.GoV1)

## IAM 認証と AWS SDK for Go V2 を使用した接続
<a name="UsingWithRDS.IAMDBAuth.Connecting.GoV2"></a>

IAM 認証と AWS SDK for Go V2 を使用して DB インスタンスに接続できます

以下のコード例で、認証トークンを生成し、それを使用して DB インスタンスに接続する方法を示します。

このコードで MariaDB インスタンスまたは MySQL DB インスタンスに接続します。

```
package main
                
import (
     "context"
     "database/sql"
     "fmt"

     "github.com/aws/aws-sdk-go-v2/config"
     "github.com/aws/aws-sdk-go-v2/feature/rds/auth"
     _ "github.com/go-sql-driver/mysql"
)

func main() {

     var dbName string = "DatabaseName"
     var dbUser string = "DatabaseUser"
     var dbHost string = "mysqldb.123456789012.us-east-1.rds.amazonaws.com"
     var dbPort int = 3306
     var dbEndpoint string = fmt.Sprintf("%s:%d", dbHost, dbPort)
     var region string = "us-east-1"

    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
    	panic("configuration error: " + err.Error())
    }

    authenticationToken, err := auth.BuildAuthToken(
    	context.TODO(), dbEndpoint, region, dbUser, cfg.Credentials)
    if err != nil {
	    panic("failed to create authentication token: " + err.Error())
    }

    dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?tls=true&allowCleartextPasswords=true",
        dbUser, authenticationToken, dbEndpoint, dbName,
    )

    db, err := sql.Open("mysql", dsn)
    if err != nil {
        panic(err)
    }

    err = db.Ping()
    if err != nil {
        panic(err)
    }
}
```

このコードで PostgreSQL DB インスタンスに接続します。

```
package main

import (
     "context"
     "database/sql"
     "fmt"

     "github.com/aws/aws-sdk-go-v2/config"
     "github.com/aws/aws-sdk-go-v2/feature/rds/auth"
     _ "github.com/lib/pq"
)

func main() {

     var dbName string = "DatabaseName"
     var dbUser string = "DatabaseUser"
     var dbHost string = "postgresmydb.123456789012.us-east-1.rds.amazonaws.com"
     var dbPort int = 5432
     var dbEndpoint string = fmt.Sprintf("%s:%d", dbHost, dbPort)
     var region string = "us-east-1"

    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
    	panic("configuration error: " + err.Error())
    }

    authenticationToken, err := auth.BuildAuthToken(
    	context.TODO(), dbEndpoint, region, dbUser, cfg.Credentials)
    if err != nil {
	    panic("failed to create authentication token: " + err.Error())
    }

    dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s",
        dbHost, dbPort, dbUser, authenticationToken, dbName,
    )

    db, err := sql.Open("postgres", dsn)
    if err != nil {
        panic(err)
    }

    err = db.Ping()
    if err != nil {
        panic(err)
    }
}
```

プロキシ経由で DB インスタンスに接続する場合は、「[IAM 認証を使用したデータベースへの接続](rds-proxy-connecting.md#rds-proxy-connecting-iam)」を参照してください。

## IAM 認証と AWS SDK for Go V1 を使用した接続。
<a name="UsingWithRDS.IAMDBAuth.Connecting.GoV1"></a>

IAM 認証と AWS SDK for Go V1 を使用して DB インスタンスに接続できます

以下のコード例で、認証トークンを生成し、それを使用して DB インスタンスに接続する方法を示します。

このコードで MariaDB インスタンスまたは MySQL DB インスタンスに接続します。

```
package main
         
import (
    "database/sql"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go/aws/credentials"
    "github.com/aws/aws-sdk-go/service/rds/rdsutils"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    dbName := "app"
    dbUser := "jane_doe"
    dbHost := "mysqldb.123456789012.us-east-1.rds.amazonaws.com"
    dbPort := 3306
    dbEndpoint := fmt.Sprintf("%s:%d", dbHost, dbPort)
    region := "us-east-1"

    creds := credentials.NewEnvCredentials()
    authToken, err := rdsutils.BuildAuthToken(dbEndpoint, region, dbUser, creds)
    if err != nil {
        panic(err)
    }

    dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?tls=true&allowCleartextPasswords=true",
        dbUser, authToken, dbEndpoint, dbName,
    )

    db, err := sql.Open("mysql", dsn)
    if err != nil {
        panic(err)
    }

    err = db.Ping()
    if err != nil {
        panic(err)
    }
}
```

このコードで PostgreSQL DB インスタンスに接続します。

```
package main

import (
	"database/sql"
	"fmt"

	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/service/rds/rdsutils"
	_ "github.com/lib/pq"
)

func main() {
    dbName := "app"
    dbUser := "jane_doe"
    dbHost := "postgresmydb.123456789012.us-east-1.rds.amazonaws.com"
    dbPort := 5432
    dbEndpoint := fmt.Sprintf("%s:%d", dbHost, dbPort)
    region := "us-east-1"

    creds := credentials.NewEnvCredentials()
    authToken, err := rdsutils.BuildAuthToken(dbEndpoint, region, dbUser, creds)
    if err != nil {
        panic(err)
    }

    dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s",
        dbHost, dbPort, dbUser, authToken, dbName,
    )

    db, err := sql.Open("postgres", dsn)
    if err != nil {
        panic(err)
    }

    err = db.Ping()
    if err != nil {
        panic(err)
    }
}
```

プロキシ経由で DB インスタンスに接続する場合は、「[IAM 認証を使用したデータベースへの接続](rds-proxy-connecting.md#rds-proxy-connecting-iam)」を参照してください。

# IAM 認証および AWS SDK for Java を使用した DB インスタンスへの接続
<a name="UsingWithRDS.IAMDBAuth.Connecting.Java"></a>

次に説明するように、AWS SDK for Java を使用して、RDS for MariaDB、MySQL、または PostgreSQL DB インスタンスに接続できます。

**前提条件**  
IAM 認証を使用して DB インスタンスに接続するための前提条件は以下のとおりです。
+ [IAM データベース認証の有効化と無効化](UsingWithRDS.IAMDBAuth.Enabling.md)
+ [IAM データベースアクセス用の IAM ポリシーの作成と使用](UsingWithRDS.IAMDBAuth.IAMPolicy.md)
+ [IAM 認証を使用したデータベースアカウントの作成](UsingWithRDS.IAMDBAuth.DBAccounts.md)
+ [AWS SDK for Java をセットアップする](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-install.html)

SDK for Java 2.x の使用方法の例については、「[SDK for Java 2.x を使用した Amazon RDS の例](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/java_rds_code_examples.html)」を参照してください。AWS Advanced JDBC Wrapper を使用することもできます。「[AWS Advanced JDBC Wrapper ドキュメント](https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/Documentation.md)」を参照してください。

**Topics**
+ [IAM 認証トークンの生成](#UsingWithRDS.IAMDBAuth.Connecting.Java.AuthToken)
+ [IAM 認証トークンを手動で構築する](#UsingWithRDS.IAMDBAuth.Connecting.Java.AuthToken2)
+ [DB インスタンスへの接続](#UsingWithRDS.IAMDBAuth.Connecting.Java.AuthToken.Connect)

## IAM 認証トークンの生成
<a name="UsingWithRDS.IAMDBAuth.Connecting.Java.AuthToken"></a>

AWS SDK for Java を使用してプログラムを作成する場合、`RdsIamAuthTokenGenerator` クラスを使用して署名付き認証トークンを取得できます。このクラスを使用するには、AWS 認証情報を提供する必要があります。これを行うには、`DefaultAWSCredentialsProviderChain` クラスのインスタンスを作成します。`DefaultAWSCredentialsProviderChain` は、[デフォルトの認証情報プロバイダチェーン](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default)で見つける初期の AWS のアクセスキーとシークレットキーを使用します。AWS アクセスキーの詳細については、「[ユーザーのアクセスキーの管理](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)」を参照してください。

**注記**  
DB インスタンス エンドポイントの代わりに、カスタム Route 53 DNS レコードを使用して認証トークンを生成することはできません。

`RdsIamAuthTokenGenerator` のインスタンスを作成した後、`getAuthToken` メソッドを呼び出して、署名済みトークンを取得できます。AWS リージョン、ホスト名、ポート番号、およびユーザー名を指定します。次のコード例はこれを行う方法を示しています。

```
package com.amazonaws.codesamples;

import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.services.rds.auth.GetIamAuthTokenRequest;
import com.amazonaws.services.rds.auth.RdsIamAuthTokenGenerator;

public class GenerateRDSAuthToken {

    public static void main(String[] args) {

	    String region = "us-west-2";
	    String hostname = "rdsmysql.123456789012.us-west-2.rds.amazonaws.com";
	    String port = "3306";
	    String username = "jane_doe";
	
	    System.out.println(generateAuthToken(region, hostname, port, username));
    }

    static String generateAuthToken(String region, String hostName, String port, String username) {

	    RdsIamAuthTokenGenerator generator = RdsIamAuthTokenGenerator.builder()
		    .credentials(new DefaultAWSCredentialsProviderChain())
		    .region(region)
		    .build();

	    String authToken = generator.getAuthToken(
		    GetIamAuthTokenRequest.builder()
		    .hostname(hostName)
		    .port(Integer.parseInt(port))
		    .userName(username)
		    .build());
	    
	    return authToken;
    }

}
```

## IAM 認証トークンを手動で構築する
<a name="UsingWithRDS.IAMDBAuth.Connecting.Java.AuthToken2"></a>

Java では、認証トークンを生成するための最も簡単な方法は、`RdsIamAuthTokenGenerator` を使用することです。このクラスは、認証トークンを作成した後、AWS 署名バージョン 4 を使用してサインインします。詳細については、*AWS 全般のリファレンス*の「[Signature Version 4 の署名プロセス](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)」を参照してください。

ただし、次のコード例に示すように、認証トークンを手動で構築して署名できます。

```
package com.amazonaws.codesamples;

import com.amazonaws.SdkClientException;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.auth.SigningAlgorithm;
import com.amazonaws.util.BinaryUtils;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SortedMap;
import java.util.TreeMap;

import static com.amazonaws.auth.internal.SignerConstants.AWS4_TERMINATOR;
import static com.amazonaws.util.StringUtils.UTF8;

public class CreateRDSAuthTokenManually {
    public static String httpMethod = "GET";
    public static String action = "connect";
    public static String canonicalURIParameter = "/";
    public static SortedMap<String, String> canonicalQueryParameters = new TreeMap();
    public static String payload = StringUtils.EMPTY;
    public static String signedHeader = "host";
    public static String algorithm = "AWS4-HMAC-SHA256";
    public static String serviceName = "rds-db";
    public static String requestWithoutSignature;

    public static void main(String[] args) throws Exception {

        String region = "us-west-2";
        String instanceName = "rdsmysql.123456789012.us-west-2.rds.amazonaws.com";
        String port = "3306";
        String username = "jane_doe";
	
        Date now = new Date();
        String date = new SimpleDateFormat("yyyyMMdd").format(now);
        String dateTimeStamp = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'").format(now);
        DefaultAWSCredentialsProviderChain creds = new DefaultAWSCredentialsProviderChain();
	    String awsAccessKey = creds.getCredentials().getAWSAccessKeyId();
	    String awsSecretKey = creds.getCredentials().getAWSSecretKey();
        String expiryMinutes = "900";
        
        System.out.println("Step 1:  Create a canonical request:");
        String canonicalString = createCanonicalString(username, awsAccessKey, date, dateTimeStamp, region, expiryMinutes, instanceName, port);
        System.out.println(canonicalString);
        System.out.println();

        System.out.println("Step 2:  Create a string to sign:");        
        String stringToSign = createStringToSign(dateTimeStamp, canonicalString, awsAccessKey, date, region);
        System.out.println(stringToSign);
        System.out.println();

        System.out.println("Step 3:  Calculate the signature:");        
        String signature = BinaryUtils.toHex(calculateSignature(stringToSign, newSigningKey(awsSecretKey, date, region, serviceName)));
        System.out.println(signature);
        System.out.println();

        System.out.println("Step 4:  Add the signing info to the request");                
        System.out.println(appendSignature(signature));
        System.out.println();
        
    }

    //Step 1: Create a canonical request date should be in format YYYYMMDD and dateTime should be in format YYYYMMDDTHHMMSSZ
    public static String createCanonicalString(String user, String accessKey, String date, String dateTime, String region, String expiryPeriod, String hostName, String port) throws Exception {
        canonicalQueryParameters.put("Action", action);
        canonicalQueryParameters.put("DBUser", user);
        canonicalQueryParameters.put("X-Amz-Algorithm", "AWS4-HMAC-SHA256");
        canonicalQueryParameters.put("X-Amz-Credential", accessKey + "%2F" + date + "%2F" + region + "%2F" + serviceName + "%2Faws4_request");
        canonicalQueryParameters.put("X-Amz-Date", dateTime);
        canonicalQueryParameters.put("X-Amz-Expires", expiryPeriod);
        canonicalQueryParameters.put("X-Amz-SignedHeaders", signedHeader);
        String canonicalQueryString = "";
        while(!canonicalQueryParameters.isEmpty()) {
            String currentQueryParameter = canonicalQueryParameters.firstKey();
            String currentQueryParameterValue = canonicalQueryParameters.remove(currentQueryParameter);
            canonicalQueryString = canonicalQueryString + currentQueryParameter + "=" + currentQueryParameterValue;
            if (!currentQueryParameter.equals("X-Amz-SignedHeaders")) {
                canonicalQueryString += "&";
            }
        }
        String canonicalHeaders = "host:" + hostName + ":" + port + '\n';
        requestWithoutSignature = hostName + ":" + port + "/?" + canonicalQueryString;

        String hashedPayload = BinaryUtils.toHex(hash(payload));
        return httpMethod + '\n' + canonicalURIParameter + '\n' + canonicalQueryString + '\n' + canonicalHeaders + '\n' + signedHeader + '\n' + hashedPayload;

    }

    //Step 2: Create a string to sign using sig v4
    public static String createStringToSign(String dateTime, String canonicalRequest, String accessKey, String date, String region) throws Exception {
        String credentialScope = date + "/" + region + "/" + serviceName + "/aws4_request";
        return algorithm + '\n' + dateTime + '\n' + credentialScope + '\n' + BinaryUtils.toHex(hash(canonicalRequest));

    }

    //Step 3: Calculate signature
    /**
     * Step 3 of the &AWS; Signature version 4 calculation. It involves deriving
     * the signing key and computing the signature. Refer to
     * http://docs.aws.amazon
     * .com/general/latest/gr/sigv4-calculate-signature.html
     */
    public static byte[] calculateSignature(String stringToSign,
                                            byte[] signingKey) {
        return sign(stringToSign.getBytes(Charset.forName("UTF-8")), signingKey,
                SigningAlgorithm.HmacSHA256);
    }

    public static byte[] sign(byte[] data, byte[] key,
                          SigningAlgorithm algorithm) throws SdkClientException {
        try {
            Mac mac = algorithm.getMac();
            mac.init(new SecretKeySpec(key, algorithm.toString()));
            return mac.doFinal(data);
        } catch (Exception e) {
            throw new SdkClientException(
                    "Unable to calculate a request signature: "
                            + e.getMessage(), e);
        }
    }

    public static byte[] newSigningKey(String secretKey,
                                   String dateStamp, String regionName, String serviceName) {
        byte[] kSecret = ("AWS4" + secretKey).getBytes(Charset.forName("UTF-8"));
        byte[] kDate = sign(dateStamp, kSecret, SigningAlgorithm.HmacSHA256);
        byte[] kRegion = sign(regionName, kDate, SigningAlgorithm.HmacSHA256);
        byte[] kService = sign(serviceName, kRegion,
                SigningAlgorithm.HmacSHA256);
        return sign(AWS4_TERMINATOR, kService, SigningAlgorithm.HmacSHA256);
    }

    public static byte[] sign(String stringData, byte[] key,
                       SigningAlgorithm algorithm) throws SdkClientException {
        try {
            byte[] data = stringData.getBytes(UTF8);
            return sign(data, key, algorithm);
        } catch (Exception e) {
            throw new SdkClientException(
                    "Unable to calculate a request signature: "
                            + e.getMessage(), e);
        }
    }

    //Step 4: append the signature
    public static String appendSignature(String signature) {
        return requestWithoutSignature + "&X-Amz-Signature=" + signature;
    }

    public static byte[] hash(String s) throws Exception {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(s.getBytes(UTF8));
            return md.digest();
        } catch (Exception e) {
            throw new SdkClientException(
                    "Unable to compute hash while signing request: "
                            + e.getMessage(), e);
        }
    }
}
```

## DB インスタンスへの接続
<a name="UsingWithRDS.IAMDBAuth.Connecting.Java.AuthToken.Connect"></a>

次のコード例では、認証トークンを生成し、それを使用して MariaDB または MySQL を実行しているインスタンスに接続する方法を示しています。

このコードサンプルを実行するには、AWS SDK for Java サイトにある [AWS](https://aws.amazon.com/sdk-for-java/) が必要です。また、以下が必要になります。
+ MySQL Connector/J。 このコードの例は `mysql-connector-java-5.1.33-bin.jar` でテストされています。
+ AWS リージョンに固有の、Amazon RDS の中間証明書。(詳細については、[SSL/TLS を使用した DB インスタンスまたはクラスターへの接続の暗号化](UsingWithRDS.SSL.md) を参照してください)。クラスローダーは、実行時にこの Java コード例と同じディレクトリで証明書を探し、クラスローダーがその証明書を見つけられるようにします。
+ 必要に応じて以下の可変の値を変更します。
  + `RDS_INSTANCE_HOSTNAME` - アクセス先の DB インスタンスのホスト名。
  + `RDS_INSTANCE_PORT` - PostgreSQL DB インスタンスへの接続に使用されるポート番号。
  + `REGION_NAME` - DB インスタンスが実行中の AWS リージョン
  + `DB_USER` - アクセス先のデータベースアカウント。
  + `SSL_CERTIFICATE` - AWS リージョンに固有の、Amazon RDS の SSL 証明書。

    AWS リージョンの証明書をダウンロードするには、[SSL/TLS を使用した DB インスタンスまたはクラスターへの接続の暗号化](UsingWithRDS.SSL.md) を参照してください。この Java プログラムファイルと同じディレクトリに SSL 証明書を配置し、クラスローダーが実行時にその証明書を見つけられるようにします。

このコード例では、[デフォルトの認証情報プロバイダチェーン](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default)から AWS 認証情報を取得します。

**注記**  
セキュリティ上のベストプラクティスとして、ここに示されているプロンプト以外の `DEFAULT_KEY_STORE_PASSWORD` のパスワードを指定してください。

```
package com.amazonaws.samples;

import com.amazonaws.services.rds.auth.RdsIamAuthTokenGenerator;
import com.amazonaws.services.rds.auth.GetIamAuthTokenRequest;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.auth.AWSStaticCredentialsProvider;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

import java.net.URL;

public class IAMDatabaseAuthenticationTester {
    //&AWS; Credentials of the IAM user with policy enabling IAM Database Authenticated access to the db by the db user.
    private static final DefaultAWSCredentialsProviderChain creds = new DefaultAWSCredentialsProviderChain();
    private static final String AWS_ACCESS_KEY = creds.getCredentials().getAWSAccessKeyId();
    private static final String AWS_SECRET_KEY = creds.getCredentials().getAWSSecretKey();

    //Configuration parameters for the generation of the IAM Database Authentication token
    private static final String RDS_INSTANCE_HOSTNAME = "rdsmysql.123456789012.us-west-2.rds.amazonaws.com";
    private static final int RDS_INSTANCE_PORT = 3306;
    private static final String REGION_NAME = "us-west-2";
    private static final String DB_USER = "jane_doe";
    private static final String JDBC_URL = "jdbc:mysql://" + RDS_INSTANCE_HOSTNAME + ":" + RDS_INSTANCE_PORT;

    private static final String SSL_CERTIFICATE = "rds-ca-2019-us-west-2.pem";

    private static final String KEY_STORE_TYPE = "JKS";
    private static final String KEY_STORE_PROVIDER = "SUN";
    private static final String KEY_STORE_FILE_PREFIX = "sys-connect-via-ssl-test-cacerts";
    private static final String KEY_STORE_FILE_SUFFIX = ".jks";
    private static final String DEFAULT_KEY_STORE_PASSWORD = "changeit";

    public static void main(String[] args) throws Exception {
        //get the connection
        Connection connection = getDBConnectionUsingIam();

        //verify the connection is successful
        Statement stmt= connection.createStatement();
        ResultSet rs=stmt.executeQuery("SELECT 'Success!' FROM DUAL;");
        while (rs.next()) {
        	    String id = rs.getString(1);
            System.out.println(id); //Should print "Success!"
        }

        //close the connection
        stmt.close();
        connection.close();
        
        clearSslProperties();
        
    }

    /**
     * This method returns a connection to the db instance authenticated using IAM Database Authentication
     * @return
     * @throws Exception
     */
    private static Connection getDBConnectionUsingIam() throws Exception {
        setSslProperties();
        return DriverManager.getConnection(JDBC_URL, setMySqlConnectionProperties());
    }

    /**
     * This method sets the mysql connection properties which includes the IAM Database Authentication token
     * as the password. It also specifies that SSL verification is required.
     * @return
     */
    private static Properties setMySqlConnectionProperties() {
        Properties mysqlConnectionProperties = new Properties();
        mysqlConnectionProperties.setProperty("verifyServerCertificate","true");
        mysqlConnectionProperties.setProperty("useSSL", "true");
        mysqlConnectionProperties.setProperty("user",DB_USER);
        mysqlConnectionProperties.setProperty("password",generateAuthToken());
        return mysqlConnectionProperties;
    }

    /**
     * This method generates the IAM Auth Token.
     * An example IAM Auth Token would look like follows:
     * btusi123---cmz7kenwo2ye---rds---cn-north-1.amazonaws.com.rproxy.goskope.com.cn:3306/?Action=connect&DBUser=iamtestuser&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20171003T010726Z&X-Amz-SignedHeaders=host&X-Amz-Expires=899&X-Amz-Credential=AKIAPFXHGVDI5RNFO4AQ%2F20171003%2Fcn-north-1%2Frds-db%2Faws4_request&X-Amz-Signature=f9f45ef96c1f770cdad11a53e33ffa4c3730bc03fdee820cfdf1322eed15483b
     * @return
     */
    private static String generateAuthToken() {
        BasicAWSCredentials awsCredentials = new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY);

        RdsIamAuthTokenGenerator generator = RdsIamAuthTokenGenerator.builder()
                .credentials(new AWSStaticCredentialsProvider(awsCredentials)).region(REGION_NAME).build();
        return generator.getAuthToken(GetIamAuthTokenRequest.builder()
                .hostname(RDS_INSTANCE_HOSTNAME).port(RDS_INSTANCE_PORT).userName(DB_USER).build());
    }

    /**
     * This method sets the SSL properties which specify the key store file, its type and password:
     * @throws Exception
     */
    private static void setSslProperties() throws Exception {
        System.setProperty("javax.net.ssl.trustStore", createKeyStoreFile());
        System.setProperty("javax.net.ssl.trustStoreType", KEY_STORE_TYPE);
        System.setProperty("javax.net.ssl.trustStorePassword", DEFAULT_KEY_STORE_PASSWORD);
    }

    /**
     * This method returns the path of the Key Store File needed for the SSL verification during the IAM Database Authentication to
     * the db instance.
     * @return
     * @throws Exception
     */
    private static String createKeyStoreFile() throws Exception {
        return createKeyStoreFile(createCertificate()).getPath();
    }

    /**
     *  This method generates the SSL certificate
     * @return
     * @throws Exception
     */
    private static X509Certificate createCertificate() throws Exception {
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        URL url = new File(SSL_CERTIFICATE).toURI().toURL();
        if (url == null) {
            throw new Exception();
        }
        try (InputStream certInputStream = url.openStream()) {
            return (X509Certificate) certFactory.generateCertificate(certInputStream);
        }
    }

    /**
     * This method creates the Key Store File
     * @param rootX509Certificate - the SSL certificate to be stored in the KeyStore
     * @return
     * @throws Exception
     */
    private static File createKeyStoreFile(X509Certificate rootX509Certificate) throws Exception {
        File keyStoreFile = File.createTempFile(KEY_STORE_FILE_PREFIX, KEY_STORE_FILE_SUFFIX);
        try (FileOutputStream fos = new FileOutputStream(keyStoreFile.getPath())) {
            KeyStore ks = KeyStore.getInstance(KEY_STORE_TYPE, KEY_STORE_PROVIDER);
            ks.load(null);
            ks.setCertificateEntry("rootCaCertificate", rootX509Certificate);
            ks.store(fos, DEFAULT_KEY_STORE_PASSWORD.toCharArray());
        }
        return keyStoreFile;
    }
    
    /**
     * This method clears the SSL properties.
     * @throws Exception
     */
    private static void clearSslProperties() throws Exception {
           System.clearProperty("javax.net.ssl.trustStore");
           System.clearProperty("javax.net.ssl.trustStoreType");
           System.clearProperty("javax.net.ssl.trustStorePassword"); 
    }
    
}
```

プロキシ経由で DB インスタンスに接続する場合は、「[IAM 認証を使用したデータベースへの接続](rds-proxy-connecting.md#rds-proxy-connecting-iam)」を参照してください。

# IAM 認証および AWS SDK for Python (Boto3) を使用した DB インスタンスへの接続
<a name="UsingWithRDS.IAMDBAuth.Connecting.Python"></a>

次に説明するように、AWS SDK for Python (Boto3) を使用して、RDS for MariaDB、MySQL、または PostgreSQL DB インスタンスに接続できます。

**前提条件**  
IAM 認証を使用して DB インスタンスに接続するための前提条件は以下のとおりです。
+ [IAM データベース認証の有効化と無効化](UsingWithRDS.IAMDBAuth.Enabling.md)
+ [IAM データベースアクセス用の IAM ポリシーの作成と使用](UsingWithRDS.IAMDBAuth.IAMPolicy.md)
+ [IAM 認証を使用したデータベースアカウントの作成](UsingWithRDS.IAMDBAuth.DBAccounts.md)

さらに、サンプルコード内のインポートされるライブラリがシステムに存在することを確認してください。

**例**  
コード例では、共有認証情報のプロファイルを使用します。認証情報の指定については、AWS SDK for Python (Boto3) ドキュメントの「[認証情報](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html)」を参照してください。

以下のコード例で、認証トークンを生成し、それを使用して DB インスタンスに接続する方法を示します。

このコードサンプルを実行するには、AWS SDK for Python (Boto3) サイトにある [AWS](https://aws.amazon.com/sdk-for-python/) が必要です。

必要に応じて以下の可変の値を変更します。
+ `ENDPOINT` - アクセス先の DB インスタンスのエンドポイント
+ `PORT` - DB インスタンスへの接続に使用するポート番号
+ `USER` - アクセス先のデータベースアカウント
+ `REGION` - DB インスタンスが実行中の AWS リージョン
+ `DBNAME` - アクセス先のデータベース
+ `SSLCERTIFICATE` － Amazon RDS の SSL 証明書へのフルパス

  `ssl_ca` を使用する場合、SSL 証明書を指定します。SSL 証明書をダウンロードするには [SSL/TLS を使用した DB インスタンスまたはクラスターへの接続の暗号化](UsingWithRDS.SSL.md) を参照ください。

**注記**  
DB インスタンス エンドポイントの代わりに、カスタム Route 53 DNS レコードを使用して認証トークンを生成することはできません。

このコードで MariaDB インスタンスまたは MySQL DB インスタンスに接続します。

このコードを実行する前に、[Python Package Index](https://pypi.org/project/PyMySQL/) の手順に従って PyMySQL ドライバーをインストールしてください。

```
import pymysql
import sys
import boto3
import os

ENDPOINT="mysqldb.123456789012.us-east-1.rds.amazonaws.com"
PORT="3306"
USER="jane_doe"
REGION="us-east-1"
DBNAME="mydb"
os.environ['LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN'] = '1'

#gets the credentials from .aws/credentials
session = boto3.Session(profile_name='default')
client = session.client('rds')

token = client.generate_db_auth_token(DBHostname=ENDPOINT, Port=PORT, DBUsername=USER, Region=REGION)

try:
    conn =  pymysql.connect(auth_plugin_map={'mysql_clear_password':None},host=ENDPOINT, user=USER, password=token, port=PORT, database=DBNAME, ssl_ca='SSLCERTIFICATE', ssl_verify_identity=True, ssl_verify_cert=True)
    cur = conn.cursor()
    cur.execute("""SELECT now()""")
    query_results = cur.fetchall()
    print(query_results)
except Exception as e:
    print("Database connection failed due to {}".format(e))
```

このコードで PostgreSQL DB インスタンスに接続します。

このコードを実行する前に、[Psycopg documentation](https://pypi.org/project/psycopg2/) の手順に従って `psycopg2` をインストールしてください。

```
import psycopg2
import sys
import boto3
import os

ENDPOINT="postgresmydb.123456789012.us-east-1.rds.amazonaws.com"
PORT="5432"
USER="jane_doe"
REGION="us-east-1"
DBNAME="mydb"

#gets the credentials from .aws/credentials
session = boto3.Session(profile_name='RDSCreds')
client = session.client('rds')

token = client.generate_db_auth_token(DBHostname=ENDPOINT, Port=PORT, DBUsername=USER, Region=REGION)

try:
    conn = psycopg2.connect(host=ENDPOINT, port=PORT, database=DBNAME, user=USER, password=token, sslrootcert="SSLCERTIFICATE")
    cur = conn.cursor()
    cur.execute("""SELECT now()""")
    query_results = cur.fetchall()
    print(query_results)
except Exception as e:
    print("Database connection failed due to {}".format(e))
```

プロキシ経由で DB インスタンスに接続する場合は、「[IAM 認証を使用したデータベースへの接続](rds-proxy-connecting.md#rds-proxy-connecting-iam)」を参照してください。