Autenticazione con IAM - Amazon MemoryDB

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Autenticazione con IAM

Panoramica

Con IAM Authentication puoi autenticare una connessione a MemoryDB utilizzando identità AWS IAM, quando il cluster è configurato per utilizzare Redis OSS versione 7 o successiva. Ciò consente di consolidare il modello di sicurezza e semplificare molte attività di sicurezza amministrative. Con IAM Authentication puoi configurare un controllo granulare degli accessi per ogni singolo cluster di MemoryDB e utente di MemoryDB e seguire i principi delle autorizzazioni con privilegi minimi. L'autenticazione IAM per MemoryDB funziona fornendo un token di autenticazione IAM di breve durata anziché una password utente MemoryDB di lunga durata nell'OSS o nel comando Redis. AUTH HELLO Per ulteriori informazioni sul token di autenticazione IAM, fai riferimento al processo di firma Signature Version 4 nella Guida di riferimento AWS generale e all'esempio di codice riportato di seguito.

Puoi utilizzare le identità IAM e le relative politiche associate per limitare ulteriormente l'accesso a Redis OSS. Puoi anche concedere l'accesso agli utenti dei loro provider di identità federati direttamente ai cluster MemoryDB.

Per utilizzare AWS IAM con MemoryDB, devi prima creare un utente MemoryDB con la modalità di autenticazione impostata su IAM, quindi puoi creare o riutilizzare un'identità IAM. L'identità IAM necessita di una policy associata per concedere l'memorydb:Connectazione al cluster MemoryDB e all'utente MemoryDB. Una volta configurato, puoi creare un token di autenticazione IAM utilizzando AWS le credenziali dell'utente o del ruolo IAM. Infine, è necessario fornire il token di autenticazione IAM di breve durata come password nel client Redis OSS durante la connessione al nodo del cluster MemoryDB. Un client Redis OSS con supporto per il provider di credenziali può generare automaticamente le credenziali temporanee per ogni nuova connessione. MemoryDB eseguirà l'autenticazione IAM per le richieste di connessione degli utenti di MemoryDB abilitati a IAM e convaliderà le richieste di connessione con IAM.

Limitazioni

Durante l'utilizzo dell'autenticazione IAM, valgono le seguenti limitazioni:

  • L'autenticazione IAM è disponibile quando si utilizza la versione 7.0 o successiva del motore Redis OSS.

  • Il token di autenticazione IAM è valido per 15 minuti. Per connessioni di lunga durata, consigliamo di utilizzare un client Redis OSS che supporti un'interfaccia con un provider di credenziali.

  • Una connessione autenticata IAM a MemoryDB verrà automaticamente disconnessa dopo 12 ore. La connessione può essere prolungata per 12 ore inviando un comando AUTH o HELLO con un nuovo token di autenticazione IAM.

  • L'autenticazione IAM non è supportata nei comandi MULTI EXEC.

  • Attualmente, l'autenticazione IAM non supporta nessuna delle chiavi di contesto delle condizioni globali. Per ulteriori informazioni sulle chiavi di contesto delle condizioni globali, consultare Chiavi di contesto delle condizioni globali AWS nella Guida per l'utente di IAM.

Installazione

Per impostare l'autenticazione IAM:

  1. Creazione di un cluster

    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
  2. Crea un documento della policy di attendibilità IAM per il ruolo, come mostrato di seguito, che consenta all'account di assumere il nuovo ruolo. Salva la policy in un file denominato trust-policy.json.

    { "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:root" }, "Action": "sts:AssumeRole" } }
  3. Crea un documento della policy IAM, come mostrato di seguito. Salva la policy in un file denominato 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" ] } ] }
  4. Crea un ruolo IAM.

    aws iam create-role \ --role-name "memorydb-iam-auth-app" \ --assume-role-policy-document file://trust-policy.json
  5. Creare la policy IAM.

    aws iam create-policy \ --policy-name "memorydb-allow-all" \ --policy-document file://policy.json
  6. Allegare la policy IAM al ruolo.

    aws iam attach-role-policy \ --role-name "memorydb-iam-auth-app" \ --policy-arn "arn:aws:iam::123456789012:policy/memorydb-allow-all"
  7. Crea un nuovo utente attivato da IAM.

    aws memorydb create-user \ --user-name iam-user-01 \ --authentication-mode Type=iam \ --access-string "on ~* +@all"
  8. Crea un ACL e collega l'utente.

    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

Connessione

Connetti con token come password

È innanzitutto necessario generare il token di autenticazione IAM di breve durata utilizzando una richiesta prefirmata AWS SigV4. Dopodiché, fornisci il token di autenticazione IAM come password quando ti connetti a un cluster MemoryDB, come mostrato nell'esempio seguente.

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 Redis OSS URL with IAM Auth credentials provider RedisURI redisURI = RedisURI.builder() .withHost(host) .withPort(port) .withSsl(ssl) .withAuthentication(userName, iamAuthToken) .build(); // Create a new Lettuce Redis OSS client RedisClusterClient client = RedisClusterClient.create(redisURI); client.connect();

Di seguito è riportata la definizione per 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()); } }

Connetti con provider di credenziali

Il codice seguente mostra come autenticarsi con MemoryDB utilizzando il provider di credenziali di autenticazione 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. 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 Redis OSS credentials provider using IAM credentials. RedisCredentialsProvider redisCredentialsProvider = new RedisIAMAuthCredentialsProvider( userName, 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 cluster client RedisClusterClient client = RedisClusterClient.create(redisURI); client.connect();

Di seguito è riportato un esempio di client cluster Lettuce Redis OSS che inserisce lo IAM AuthTokenRequest in un provider di credenziali per generare automaticamente credenziali temporanee quando necessario.

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