Autenticação com o IAM
Visão geral
Com a autenticação do IAM, é possível autenticar uma conexão ao ElastiCache para Valkey ou Redis OSS usando identidades do AWS IAM, quando o cache está configurado para usar o Valkey ou o Redis OSS versão 7 ou posterior. Isso possibilita que você fortaleça seu modelo de segurança e simplifique várias tarefas administrativas de segurança. Você também pode usar a autenticação do IAM para configurar um controle de acesso refinado para cada cache do ElastiCache individual e usuário do ElastiCache seguindo os princípios das permissões de privilégio mínimo. A autenticação do IAM para o ElastiCache funciona fornecendo um token de autenticação do IAM de curta duração, em vez de uma senha de usuário do ElastiCache de longa duração no comando AUTH ou HELLO do Valkey ou Redis OSS. Para obter mais informações sobre o token de autenticação do IAM, consulte o processo de assinatura do Signature versão 4 no Guia de referência geral do AWS e no exemplo de código abaixo.
Você pode usar as identidades do IAM e suas políticas associadas para restringir ainda mais o acesso ao Valkey ou Redis OSS. Também é possível conceder acesso a usuários dos provedores de identidade federados diretamente para caches do Valkey ou Redis OSS.
Para usar o AWS IAM com o ElastiCache, primeiro é necessário criar um usuário do ElastiCache com o modo de autenticação definido como IAM. Em seguida, você pode criar ou reutilizar uma identidade do IAM. A identidade do IAM precisa de uma política associada para conceder a ação elasticache:Connect ao cache do ElastiCache e ao usuário do ElastiCache. Depois de configurado, você pode criar um token de autenticação do IAM usando as credenciais da AWS do usuário ou do perfil do IAM. Por fim, você precisa fornecer o token de autenticação do IAM de curta duração como uma senha no cliente do Valkey ou Redis OSS ao se conectar ao cache. Um cliente do Valkey ou Redis OSS com suporte para provedor de credenciais pode gerar automaticamente as credenciais temporárias para cada nova conexão. O ElastiCache executará a autenticação do IAM para solicitações de conexão de usuários do ElastiCache habilitados para o IAM e validará as solicitações de conexão com o IAM.
Limitações
Ao usar a autenticação do IAM, as seguintes limitações se aplicam:
A autenticação do IAM está disponível ao usar o ElastiCache para Valkey 7.2 e superior ou Redis OSS versão 7.0 e superior.
Para usuários do ElastiCache habilitados para o IAM, as propriedades de nome de usuário e ID de usuário devem ser idênticas.
O token de autenticação do IAM é válido por 15 minutos. Para conexões de longa duração, recomendamos usar um cliente do Valkey ou Redis OSS que suporte uma interface de provedor de credenciais.
Uma conexão autenticada pelo IAM ao ElastiCache para Valkey ou Redis OSS será desconectada automaticamente após 12 horas. A conexão pode ser prolongada por 12 horas enviando um comando
AUTHouHELLOcom um novo token de autenticação do IAM.A autenticação do IAM não tem suporte em comandos
MULTI EXEC.Atualmente, a autenticação do IAM não dá suporte às seguintes chaves de contexto de condição global:
Durante o uso da autenticação do IAM com caches sem servidor,
aws:VpcSourceIp,aws:SourceVpc,aws:SourceVpce,aws:CurrentTime,aws:EpochTimeeaws:ResourceTag/%s(de caches sem servidor associados e usuários) são compatíveis.Durante o uso da autenticação do IAM com grupos de replicação,
aws:SourceIpeaws:ResourceTag/%s(de grupos de replicação associados e usuários) são compatíveis.
Para obter mais informações sobre chaves de contexto de condição global, consulte Chaves de contexto de condição global da AWS no Guia do usuário do IAM.
Configuração
Como configurar a autenticação do IAM
Criar um cache
aws elasticache create-serverless-cache \ --serverless-cache-name cache-01 \ --description "ElastiCache IAM auth application" \ --engine redisCrie um documento de política de confiança do IAM, conforme mostrado abaixo, para o perfil que permita que sua conta assuma o novo perfil. Salve a política em um arquivo chamado trust-policy.json.
Crie um documento de política do IAM, conforme mostrado abaixo. Salve a política em um arquivo chamado policy.json.
Criar um perfil do IAM.
aws iam create-role \ --role-name "elasticache-iam-auth-app" \ --assume-role-policy-document file://trust-policy.jsonCrie a política do IAM.
aws iam create-policy \ --policy-name "elasticache-allow-all" \ --policy-document file://policy.jsonAnexe a política do IAM à função.
aws iam attach-role-policy \ --role-name "elasticache-iam-auth-app" \ --policy-arn "arn:aws:iam::123456789012:policy/elasticache-allow-all"Crie um novo usuário habilitado para o 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"Crie um grupo de usuários e anexe o usuário.
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
Conexão
Conectar com token como senha
Primeiro, é necessário gerar o token de autenticação do IAM de curta duração usando uma solicitação pré-assinada do AWS SigV4. Depois disso, você fornecerá o token de autenticação do IAM como senha ao se conectar a um cache do Valkey ou Redis OSS, conforme mostrado no exemplo abaixo.
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 with 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();
Veja abaixo a definição 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()); } }
Conectar com o provedor de credenciais
O código abaixo mostra como autenticar com o ElastiCache usando o provedor de credenciais de autenticação do 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 with 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();
Veja abaixo um exemplo de um cliente Lettuce Redis OSS que encapsula o IAMAuthTokenRequest em um provedor de credenciais para gerar automaticamente credenciais temporárias quando necessário.
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()); } }