

# IAM 인증을 사용하여 DB 인스턴스에 연결
<a name="UsingWithRDS.IAMDBAuth.Connecting"></a>

IAM 데이터베이스 인증 방식에서는 DB 인스턴스 에 연결할 때 인증 토큰을 사용합니다. *인증 토큰*이란 암호 대신 사용하는 문자열을 말합니다. 인증 토큰은 생성 후 15분 동안만 유효하며 이 시간이 지나면 만료됩니다. 만료된 토큰을 사용하여 연결하려고 하면 연결 요청이 거부됩니다.

모든 인증 토큰은 AWS 서명 버전 4를 사용하여 유효한 서명이 있어야 합니다. (자세한 내용은 *AWS 일반 참조*의 [서명 버전 4 서명 프로세스](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)를 참조하세요.) AWS SDK for Java 또는 AWS SDK for Python (Boto3)와 같은 AWS CLI 및 AWS SDK는 사용자가 생성한 각 토큰에 자동으로 서명할 수 있습니다.

AWS Lambda와 같은 AWS 서비스에서 Amazon RDS에 연결할 때 인증 토큰을 사용할 수 있습니다. 토큰을 사용하면 코드에 암호를 넣지 않아도 됩니다. 그 밖에 AWS SDK를 사용하여 인증 토큰을 프로그래밍 방식으로 생성하고 프로그래밍 방식으로 서명하는 방법도 있습니다.

IAM 인증 토큰에 서명까지 마쳤으면 이제 Amazon RDS DB 인스턴스에 연결할 수 있습니다. 다음 섹션에서는 명령줄 도구 또는 AWS SDK(예: AWS SDK for Java 또는 AWS SDK for Python (Boto3))를 사용하여 연결하는 방법에 대해 알아보겠습니다.

자세한 내용은 다음 블로그 게시물을 참조하십시오.
+ [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/)
+ [Using IAM authentication to connect with pgAdmin Amazon Aurora PostgreSQL or 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/)

**사전 조건**  
다음은 IAM 인증을 사용하여 DB 인스턴스에 연결하기 위한 사전 조건입니다.
+ [IAM 데이터베이스 인증의 활성화 및 비활성화](UsingWithRDS.IAMDBAuth.Enabling.md)
+ [IAM 데이터베이스 액세스를 위한 IAM 정책 생성 및 사용](UsingWithRDS.IAMDBAuth.IAMPolicy.md)
+ [IAM 인증을 사용하여 데이터베이스 계정 생성](UsingWithRDS.IAMDBAuth.DBAccounts.md)

**Topics**
+ [AWS 드라이버와 함께 IAM 인증을 사용하여 DB 인스턴스에 연결](IAMDBAuth.Connecting.Drivers.md)
+ [명령줄에서 IAM 인증을 사용하여 DB 인스턴스에 연결: AWS CLI 및 mysql 클라이언트](UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.md)
+ [명령줄: AWS CLI 및 psql Client에서 IAM 인증을 사용하여 DB 인스턴스에 연결](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)

# AWS 드라이버와 함께 IAM 인증을 사용하여 DB 인스턴스에 연결
<a name="IAMDBAuth.Connecting.Drivers"></a>

더 빠른 전환 및 장애 조치 시간, AWS Secrets Manager, AWS Identity and Access Management(IAM) 및 페더레이션 ID를 사용한 인증을 지원하도록 설계된 AWS 드라이버 제품군입니다. AWS 드라이버는 DB 인스턴스 상태 모니터링과 인스턴스 토폴로지 파악을 통해 새 라이터를 결정합니다. 이 접근 방식은 전환 및 장애 조치 시간을 오픈 소스 드라이버의 경우 수십 초였던 것에 비해 10초 미만으로 단축합니다.

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 인증을 통한 SQL Workbench/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 인증 토큰입니다.

인증 토큰은 수백 자의 문자로 구성됩니다. 그렇기 때문에 명령줄에서는 다루지 불편할 수도 있습니다. 이러한 문제를 해결하기 위해 토큰을 환경 변수로 저장한 후 연결할 때 이 변수를 사용하는 것도 한 가지 방법입니다. 다음은 이러한 문제 해결 방법을 설명한 예제입니다. 이 예에서 */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)을 참조하세요.

# 명령줄: AWS CLI 및 psql Client에서 IAM 인증을 사용하여 DB 인스턴스에 연결
<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)

**참고**  
IAM 인증을 통한 pgAdmin을 사용하여 데이터베이스에 연결하는 방법에 대한 자세한 내용은 블로그 게시물 [Using IAM authentication to connect with pgAdmin Amazon Aurora PostgreSQL or 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>

인증 토큰은 수백 자의 문자로 구성되므로 명령줄에서는 다루기 불편할 수 있습니다. 이러한 문제를 해결하기 위해 토큰을 환경 변수로 저장한 후 연결할 때 이 변수를 사용하는 것도 한 가지 방법입니다. 다음 예제는 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 연결에서 SSL 인증서의 엔드포인트와 비교하여 DB 인스턴스 엔드포인트를 확인합니다.
+ `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](https://aws.amazon.com/sdk-for-net/)가 필요하며 이는 AWS 사이트에서 받을 수 있습니다. `AWSSDK.CORE` 및 `AWSSDK.RDS` 패키지가 필요합니다. DB 인스턴스에 연결하려면 DB 엔진용 .NET 데이터베이스 커넥터(예: MariaDB 또는 MySQL용 MySQL커넥터 또는 PostgreSQL용 Npgsql)를 사용합니다.

이 코드는 MariaDB 또는 MySQL DB 인스턴스에 연결됩니다. 필요하다면 다음 변수 값을 변경합니다.
+ `server` - 액세스할 DB 인스턴스의 엔드포인트입니다.
+ `user` – 액세스할 데이터베이스 계정입니다.
+ `database` – 액세스할 데이터베이스입니다.
+ `port` – DB 인스턴스에 연결할 때 사용할 포트 번호입니다.
+ `SslMode` – 사용할 SSL 모드입니다.

  `SslMode=Required`을 사용하면 SSL 연결에서 SSL 인증서의 엔드포인트와 비교하여 DB 인스턴스 엔드포인트를 확인합니다.
+ `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 연결에서 SSL 인증서의 엔드포인트와 비교하여 DB 인스턴스 엔드포인트를 확인합니다.
+ `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](https://aws.amazon.com/sdk-for-go/)가 필요하며 이는 AWS 사이트에서 받을 수 있습니다.

필요하다면 다음 변수 값을 변경합니다.
+ `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)

Java 2.x용 SDK를 사용하는 방법에 대한 예제는 [Java 2.x용 SDK를 사용한 Amazon RDS 예제](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/java_rds_code_examples.html)를 참조하세요. 또한 AWS 고급 JDBC 래퍼를 사용할 수 있습니다. [AWS Advanced JDBC Wrapper documentation](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 일반 참조*의 [서명 버전 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](https://aws.amazon.com/sdk-for-java/)가 필요하며 이는 AWS 사이트에서 받을 수 있습니다. 또한 다음이 필요합니다.
+ 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) 섹션을 참조하세요. SSL 인증서는 예제 실행 시 클래스 로더가 인증서를 찾을 수 있도록 이 Java 프로그램 파일과 동일한 디렉터리에 설치합니다.

다음은 [기본 자격 증명 공급자 체인](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)](https://aws.amazon.com/sdk-for-python/)가 필요하며 이는 AWS 사이트에서 받을 수 있습니다.

필요하다면 다음 변수 값을 변경합니다.
+ `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 색인](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 설명서](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)을 참조하세요.