Authentification avec IAM - Amazon ElastiCache (RedisOSS)

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Authentification avec IAM

Présentation

Avec l'authentification IAM, vous pouvez authentifier une connexion à ElastiCache (Redis OSS) à l'aide d'identités AWS IAM, lorsque votre cache est configuré pour utiliser Redis OSS version 7 ou supérieure. Cela vous permet de renforcer votre modèle de sécurité et de simplifier de nombreuses tâches administratives de sécurité. Vous pouvez également utiliser l'authentification IAM pour configurer un contrôle d'accès précis pour chaque ElastiCache cache et chaque ElastiCache utilisateur, conformément aux principes d'autorisation du moindre privilège. L'authentification IAM pour ElastiCache (Redis OSS) fonctionne en fournissant un jeton d'authentification IAM de courte durée au lieu d'un mot de passe ElastiCache utilisateur de longue durée dans le système d'exploitation ou la commande Redis OSS. AUTH HELLO Pour plus d'informations sur le jeton d'authentification IAM, reportez-vous au processus de signature Signature version 4 du Guide de référence AWS général et à l'exemple de code ci-dessous.

Vous pouvez utiliser les identités IAM et leurs politiques associées pour restreindre davantage l'accès à Redis OSS. Vous pouvez également accorder l'accès aux utilisateurs depuis leurs fournisseurs d'identité fédérés directement aux caches Redis OSS.

Pour utiliser AWS IAM avec ElastiCache (Redis OSS), vous devez d'abord créer un ElastiCache utilisateur dont le mode d'authentification est défini sur IAM. Vous pouvez ensuite créer ou réutiliser une identité IAM. L'identité IAM a besoin d'une politique associée pour accorder l'elasticache:Connectaction au ElastiCache cache et à l' ElastiCache utilisateur. Une fois configuré, vous pouvez créer un jeton d'authentification IAM à l'aide des AWS informations d'identification de l'utilisateur ou du rôle IAM. Enfin, vous devez fournir le jeton d'authentification IAM de courte durée comme mot de passe dans votre client Redis OSS lorsque vous vous connectez à votre cache Redis OSS. Un client Redis OSS prenant en charge le fournisseur d'informations d'identification peut générer automatiquement les informations d'identification temporaires pour chaque nouvelle connexion. ElastiCache (Redis OSS) effectuera l'authentification IAM pour les demandes de connexion des ElastiCache utilisateurs compatibles IAM et validera les demandes de connexion avec IAM.

Limites

Les limites suivantes s'appliquent avec l'authentification IAM :

  • L'authentification IAM est disponible lors de l'utilisation de ElastiCache (Redis OSS) version 7.0 ou supérieure.

  • Pour les ElastiCache utilisateurs compatibles IAM, les propriétés du nom d'utilisateur et de l'identifiant utilisateur doivent être identiques.

  • Le jeton d'authentification IAM est valide pendant 15 minutes. Pour les connexions de longue durée, nous vous recommandons d'utiliser un client Redis OSS qui prend en charge une interface de fournisseur d'informations d'identification.

  • Une connexion authentifiée IAM à ElastiCache (Redis OSS) sera automatiquement déconnectée au bout de 12 heures. La connexion peut être prolongée de 12 heures en envoyant une commande AUTH ou HELLO avec un nouveau jeton d'authentification IAM.

  • L'authentification IAM n'est pas prise en charge dans les commandes MULTI EXEC.

  • Actuellement, l’authentification IAM prend en charge les clés de contexte de condition globale suivantes :

    • Lorsque vous utilisez l’authentification IAM avec des caches sans serveur, aws:VpcSourceIp, aws:SourceVpc, aws:SourceVpce, aws:CurrentTime, aws:EpochTime et aws:ResourceTag/%s (à partir des caches sans serveur et des utilisateurs associés) sont prises en charge.

    • Lorsque vous utilisez l’authentification IAM avec des groupes de réplication, aws:SourceIp et aws:ResourceTag/%s (à partir des groupes de réplication et des utilisateurs associés) sont prises en charge.

    Pour plus d'informations sur les clés de contexte de condition globale, consultez Clés de contexte de condition globale AWS dans le Guide de l'utilisateur IAM.

Configuration

Pour configurer une authentification IAM :

  1. Créez un cache.

    aws elasticache create-serverless-cache \ --serverless-cache-name cache-01 \ --description "ElastiCache IAM auth application" \ --engine redis
  2. Créez un document de stratégie d'approbation IAM, comme indiqué ci-dessous, pour votre rôle afin d'autoriser votre compte à assumer le nouveau rôle. Enregistrez la politique dans un fichier nommé trust-policy.json.

    { "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:root" }, "Action": "sts:AssumeRole" } }
  3. Créez un document de politique IAM, comme indiqué ci-dessous. Enregistrez la politique dans un fichier nommé policy.json.

    { "Version": "2012-10-17", "Statement": [ { "Effect" : "Allow", "Action" : [ "elasticache:Connect" ], "Resource" : [ "arn:aws:elasticache:us-east-1:123456789012:serverlesscache:cache-01", "arn:aws:elasticache:us-east-1:123456789012:user:iam-user-01" ] } ] }
  4. Créez un rôle IAM.

    aws iam create-role \ --role-name "elasticache-iam-auth-app" \ --assume-role-policy-document file://trust-policy.json
  5. Créez la politique IAM.

    aws iam create-policy \ --policy-name "elasticache-allow-all" \ --policy-document file://policy.json
  6. Attachez la politique gérée IAM au rôle.

    aws iam attach-role-policy \ --role-name "elasticache-iam-auth-app" \ --policy-arn "arn:aws:iam::123456789012:policy/elasticache-allow-all"
  7. Créez un compte utilisateur prenant en charge IAM.

    aws elasticache create-user \ --user-name iam-user-01 \ --user-id iam-user-01 \ --authentication-mode Type=iam \ --engine redis \ --access-string "on ~* +@all"
  8. Créez un groupe d'utilisateurs et attachez l'utilisateur.

    aws elasticache create-user-group \ --user-group-id iam-user-group-01 \ --engine redis \ --user-ids default iam-user-01 aws elasticache modify-serverless-cache \ --serverless-cache-name cache-01 \ --user-group-id iam-user-group-01

Connexion

Se connecter avec un jeton comme mot de passe

Vous devez d'abord générer le jeton d'authentification IAM de courte durée à l'aide d'une Demande pré-signée AWS SigV4. Ensuite, vous fournissez le jeton d'authentification IAM comme mot de passe lorsque vous vous connectez à un cache Redis OSS, comme indiqué dans l'exemple ci-dessous.

String userId = "insert user id"; String cacheName = "insert cache name"; boolean isServerless = true; 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 ElastiCache (Redis OSS). IAMAuthTokenRequest iamAuthTokenRequest = new IAMAuthTokenRequest(userId, cacheName, region, isServerless); String iamAuthToken = iamAuthTokenRequest.toSignedRequestUri(awsCredentialsProvider.getCredentials()); // Construct Redis OSS URL with IAM Auth credentials provider RedisURI redisURI = RedisURI.builder() .withHost(host) .withPort(port) .withSsl(ssl) .withAuthentication(userId, iamAuthToken) .build(); // Create a new Lettuce Redis OSS client RedisClient client = RedisClient.create(redisURI); client.connect();

Vous trouverez ci-dessous la définition de 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 PARAM_RESOURCE_TYPE = "ResourceType"; private static final String RESOURCE_TYPE_SERVERLESS_CACHE = "ServerlessCache"; private static final String ACTION_NAME = "connect"; private static final String SERVICE_NAME = "elasticache"; private static final long TOKEN_EXPIRY_SECONDS = 900; private final String userId; private final String cacheName; private final String region; private final boolean isServerless; public IAMAuthTokenRequest(String userId, String cacheName, String region, boolean isServerless) { this.userId = userId; this.cacheName = cacheName; this.region = region; this.isServerless = isServerless; } 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(userId)); if (isServerless) { request.addParameters(PARAM_RESOURCE_TYPE, Collections.singletonList(RESOURCE_TYPE_SERVERLESS_CACHE)); } return request; } private URI getRequestUri() { return URI.create(String.format("%s%s/", REQUEST_PROTOCOL, cacheName)); } 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()); } }

Se connecter avec un fournisseur d'informations d'identification

Le code ci-dessous montre comment s'authentifier auprès de ElastiCache (Redis OSS) à l'aide du fournisseur d'identifiants d'authentification IAM.

String userId = "insert user id"; String cacheName = "insert cache name"; boolean isServerless = true; 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 ElastiCache (Redis OSS). IAMAuthTokenRequest iamAuthTokenRequest = new IAMAuthTokenRequest(userId, cacheName, region, isServerless); // Create a Redis OSS credentials provider using IAM credentials. RedisCredentialsProvider redisCredentialsProvider = new RedisIAMAuthCredentialsProvider( userId, iamAuthTokenRequest, awsCredentialsProvider); // Construct Redis OSS URL with IAM Auth credentials provider RedisURI redisURI = RedisURI.builder() .withHost(host) .withPort(port) .withSsl(ssl) .withAuthentication(redisCredentialsProvider) .build(); // Create a new Lettuce Redis OSS client RedisClient client = RedisClient.create(redisURI); client.connect();

Vous trouverez ci-dessous un exemple de client Lettuce Redis OSS qui intègre l'IAM AuthTokenRequest dans un fournisseur d'informations d'identification pour générer automatiquement des informations d'identification temporaires en cas de besoin.

public class RedisIAMAuthCredentialsProvider implements RedisCredentialsProvider { private static final long TOKEN_EXPIRY_SECONDS = 900; private final AWSCredentialsProvider awsCredentialsProvider; private final String userId; private final IAMAuthTokenRequest iamAuthTokenRequest; private final Supplier<String> iamAuthTokenSupplier; public RedisIAMAuthCredentialsProvider(String userId, 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(userId, iamAuthTokenSupplier.get())); } private String getIamAuthToken() { return iamAuthTokenRequest.toSignedRequestUri(awsCredentialsProvider.getCredentials()); } }