翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
IAM を使用した認証
概要
IAM 認証では、クラスターが Valkey AWS または Redis OSS バージョン 7 以降を使用するように設定されている場合、IAM ID を使用して MemoryDB への接続を認証できます。これにより、セキュリティモデルを強化し、多くの管理セキュリティタスクを簡素化できます。IAM 認証では、個々の MemoryDB クラスターと MemoryDB ユーザーごとにきめ細かいアクセス制御を設定し、最小特権の権限の原則に従うことができます。MemoryDB の IAM 認証は、有効期間の長い MemoryDB ユーザーパスワードの代わりに、有効期間が短い IAM 認証トークンを AUTH
または HELLO
コマンドで提供することにより機能します。IAM 認証トークンの詳細については、「 AWS 全般のリファレンスガイド」の「署名バージョン 4 の署名プロセス」および以下のコード例を参照してください。
IAM アイデンティティとそれに関連するポリシーを使用して、Valkey または Redis OSS アクセスをさらに制限できます。また、フェデレーテッド ID プロバイダーのユーザーに MemoryDB クラスターへのアクセス権を直接付与することもできます。
MemoryDB で AWS IAM を使用するには、まず認証モードを IAM に設定して MemoryDB ユーザーを作成し、次に IAM ID を作成または再利用する必要があります。IAM アイデンティティには、MemoryDB クラスターと MemoryDB ユーザーに memorydb:Connect
アクションを許可するための関連ポリシーが必要です。設定したら、IAM ユーザーまたはロールの AWS 認証情報を使用して IAM 認証トークンを作成できます。最後に、MemoryDB クラスターノードに接続するときに、有効期間が短い IAM 認証トークンを Valkey または Redis OSS クライアントのパスワードとして指定する必要があります。認証情報プロバイダーをサポートしているクライアントは、新しい接続ごとに一時的な認証情報を自動的に生成できます。MemoryDB for Redis は、IAM が有効な MemoryDB ユーザーの接続リクエストに対して IAM 認証を実行し、その接続リクエストを IAM で検証します。
制限
IAM 認証を使用する場合、以下の制限が適用されます。
Valkey または Redis OSS エンジンバージョン 7.0 以上を使用している場合、IAM 認証が利用できます。
IAM 認証トークンは 15 分間有効です。長時間接続する場合は、認証情報プロバイダーインターフェイスをサポートする Redis OSS クライアントを使用することをお勧めします。
MemoryDB for Redis への IAM 認証された接続は、12 時間後に自動的に切断されます。新しい IAM 認証トークンを使用して
AUTH
またはHELLO
コマンドを送信することで、接続を 12 時間延長できます。IAM 認証は
MULTI EXEC
コマンドではサポートされていません。現在、IAM 認証はすべてのグローバル条件コンテキストキーをサポートしていません。グローバル条件コンテキストキーの詳細については、「IAM ユーザーガイド」の「AWS グローバル条件コンテキストキー」を参照してください。
セットアップ
IAM 認証をセットアップするには:
クラスターを作成する
aws memorydb create-cluster \ --cluster-name cluster-01 \ --description "MemoryDB IAM auth application" --node-type db.r6g.large \ --engine-version 7.0 \ --acl-name open-access
アカウントが新しいロールを引き継ぐことを許可するロール用の IAM 信頼ポリシードキュメントを以下に示すように作成します。ポリシーを trust-policy.json というファイルに保存します。
{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:root" }, "Action": "sts:AssumeRole" } }
以下に示すように、IAM ポリシードキュメントを作成します。ポリシーを policy.json というファイルに保存します。
{ "Version": "2012-10-17", "Statement": [ { "Effect" : "Allow", "Action" : [ "memorydb:connect" ], "Resource" : [ "arn:aws:memorydb:us-east-1:123456789012:cluster/cluster-01", "arn:aws:memorydb:us-east-1:123456789012:user/iam-user-01" ] } ] }
IAM ロールを作成します。
aws iam create-role \ --role-name "memorydb-iam-auth-app" \ --assume-role-policy-document file://trust-policy.json
IAM ポリシーを作成します。
aws iam create-policy \ --policy-name "memorydb-allow-all" \ --policy-document file://policy.json
IAM ポリシーをロールにアタッチします。
aws iam attach-role-policy \ --role-name "memorydb-iam-auth-app" \ --policy-arn "arn:aws:iam::123456789012:policy/memorydb-allow-all"
IAM を有効にしている新しいユーザーを作成します。
aws memorydb create-user \ --user-name iam-user-01 \ --authentication-mode Type=iam \ --access-string "on ~* +@all"
ACL を作成し、ユーザーをアタッチします。
aws memorydb create-acl \ --acl-name iam-acl-01 \ --user-names iam-user-01 aws memorydb update-cluster \ --cluster-name cluster-01 \ --acl-name iam-acl-01
接続中
トークンをパスワードとして接続
最初に、AWS SigV4 の署名済みリクエストを使用して、有効期間が短い IAM 認証トークンを生成する必要があります。その後、以下の例に示すように、MemoryDB クラスターに接続するときに IAM 認証トークンをパスワードとして指定します。
String userName = "insert user name" String clusterName = "insert cluster name" String region = "insert region" // Create a default AWS Credentials provider. // This will look for AWS credentials defined in environment variables or system properties. AWSCredentialsProvider awsCredentialsProvider = new DefaultAWSCredentialsProviderChain(); // Create an IAM authentication token request and signed it using the AWS credentials. // The pre-signed request URL is used as an IAM authentication token for MemoryDB. IAMAuthTokenRequest iamAuthTokenRequest = new IAMAuthTokenRequest(userName, clusterName, region); String iamAuthToken = iamAuthTokenRequest.toSignedRequestUri(awsCredentialsProvider.getCredentials()); // Construct URL with IAM Auth credentials provider RedisURI redisURI = RedisURI.builder() .withHost(host) .withPort(port) .withSsl(ssl) .withAuthentication(userName, iamAuthToken) .build(); // Create a new Lettuce client RedisClusterClient client = RedisClusterClient.create(redisURI); client.connect();
以下は IAMAuthTokenRequest
の定義です。
public class IAMAuthTokenRequest { private static final HttpMethodName REQUEST_METHOD = HttpMethodName.GET; private static final String REQUEST_PROTOCOL = "http://"; private static final String PARAM_ACTION = "Action"; private static final String PARAM_USER = "User"; private static final String ACTION_NAME = "connect"; private static final String SERVICE_NAME = "memorydb"; private static final long TOKEN_EXPIRY_SECONDS = 900; private final String userName; private final String clusterName; private final String region; public IAMAuthTokenRequest(String userName, String clusterName, String region) { this.userName = userName; this.clusterName = clusterName; this.region = region; } public String toSignedRequestUri(AWSCredentials credentials) throws URISyntaxException { Request<Void> request = getSignableRequest(); sign(request, credentials); return new URIBuilder(request.getEndpoint()) .addParameters(toNamedValuePair(request.getParameters())) .build() .toString() .replace(REQUEST_PROTOCOL, ""); } private <T> Request<T> getSignableRequest() { Request<T> request = new DefaultRequest<>(SERVICE_NAME); request.setHttpMethod(REQUEST_METHOD); request.setEndpoint(getRequestUri()); request.addParameters(PARAM_ACTION, Collections.singletonList(ACTION_NAME)); request.addParameters(PARAM_USER, Collections.singletonList(userName)); return request; } private URI getRequestUri() { return URI.create(String.format("%s%s/", REQUEST_PROTOCOL, clusterName)); } private <T> void sign(SignableRequest<T> request, AWSCredentials credentials) { AWS4Signer signer = new AWS4Signer(); signer.setRegionName(region); signer.setServiceName(SERVICE_NAME); DateTime dateTime = DateTime.now(); dateTime = dateTime.plus(Duration.standardSeconds(TOKEN_EXPIRY_SECONDS)); signer.presignRequest(request, credentials, dateTime.toDate()); } private static List<NameValuePair> toNamedValuePair(Map<String, List<String>> in) { return in.entrySet().stream() .map(e -> new BasicNameValuePair(e.getKey(), e.getValue().get(0))) .collect(Collectors.toList()); } }
認証情報プロバイダーに接続
以下のコードは、IAM 認証情報プロバイダーを使用して MemoryDB for Redis で認証する方法を示しています。
String userName = "insert user name" String clusterName = "insert cluster name" String region = "insert region" // Create a default AWS Credentials provider. // This will look for AWS credentials defined in environment variables or system properties. AWSCredentialsProvider awsCredentialsProvider = new DefaultAWSCredentialsProviderChain(); // Create an IAM authentication token request. Once this request is signed it can be used as an // IAM authentication token for MemoryDB. IAMAuthTokenRequest iamAuthTokenRequest = new IAMAuthTokenRequest(userName, clusterName, region); // Create a credentials provider using IAM credentials. RedisCredentialsProvider redisCredentialsProvider = new RedisIAMAuthCredentialsProvider( userName, iamAuthTokenRequest, awsCredentialsProvider); // Construct URL with IAM Auth credentials provider RedisURI redisURI = RedisURI.builder() .withHost(host) .withPort(port) .withSsl(ssl) .withAuthentication(redisCredentialsProvider) .build(); // Create a new Lettuce cluster client RedisClusterClient client = RedisClusterClient.create(redisURI); client.connect();
以下は、IAMAuthTokenRequest を認証情報プロバイダーにラップして、必要に応じて一時的な認証情報を自動生成する Lettuce クラスタークライアントの例です。
public class RedisIAMAuthCredentialsProvider implements RedisCredentialsProvider { private static final long TOKEN_EXPIRY_SECONDS = 900; private final AWSCredentialsProvider awsCredentialsProvider; private final String userName; private final IAMAuthTokenRequest iamAuthTokenRequest; private final Supplier<String> iamAuthTokenSupplier; public RedisIAMAuthCredentialsProvider(String userName, IAMAuthTokenRequest iamAuthTokenRequest, AWSCredentialsProvider awsCredentialsProvider) { this.userName = userName; this.awsCredentialsProvider = awsCredentialsProvider; this.iamAuthTokenRequest = iamAuthTokenRequest; this.iamAuthTokenSupplier = Suppliers.memoizeWithExpiration(this::getIamAuthToken, TOKEN_EXPIRY_SECONDS, TimeUnit.SECONDS); } @Override public Mono<RedisCredentials> resolveCredentials() { return Mono.just(RedisCredentials.just(userName, iamAuthTokenSupplier.get())); } private String getIamAuthToken() { return iamAuthTokenRequest.toSignedRequestUri(awsCredentialsProvider.getCredentials()); }