Como soluciono o erro “O token de segurança incluído na solicitação está expirado” ao executar aplicações Java no Amazon EC2?

Data da última atualização: 04/03/2021

Minhas aplicações Java que usam o AWS SDK for Java em uma instância do Amazon Elastic Compute Cloud (Amazon EC2) recebem uma exceção semelhante à seguinte:

com.amazonaws.AmazonServiceException: The security token included in the request is expired (Service: AmazonSQS; Status Code: 403; Error Code: ExpiredToken; Request ID: 12a345b6-78cd-901e-fg23-45hi67890jkl)

Como posso solucionar isso?

Breve descrição

Todas as solicitações de API de aplicação para Amazon Web Services (AWS) devem ser assinadas criptograficamente usando credenciais emitidas pela AWS.

Se a aplicação usar credenciais temporárias ao criar um cliente da AWS, as credenciais expirarão no intervalo de tempo especificado durante a criação. Você deve atualizar as credenciais antes que elas expirem.

Outro motivo para a expiração é usar o horário incorreto. É fundamental usar uma referência de horário consistente e precisa para várias tarefas e processos do servidor. Se a data e a hora da instância não estiverem definidas corretamente, as credenciais da AWS serão rejeitadas.

Se a aplicação estiver sendo executado em uma instância do Amazon EC2, é uma prática recomendada usar uma função do AWS Identity and Access Management (IAM) atribuída à instância. O uso de uma função do IAM permite utilizar um criador padrão de serviços. O cliente construtor padrão procura credenciais usando a cadeia de provedores de credenciais padrão, na seguinte ordem:

  1. Nas variáveis de ambiente do sistema: AWS_ACCESS_KEY_ID e AWS_SECRET_ACCESS_KEY.
  2. Nas propriedades do sistema Java: aws.AccessKeyId e aws.SecretKey.
  3. No arquivo de credenciais padrão (a localização desse arquivo varia de acordo com a plataforma).
  4. Nas credenciais de perfil da instância contidas nos metadados da instância associados à função do IAM para a instância do EC2. Anexar um perfil da instância à instância adiciona credenciais de perfil de instância à cadeia de provedores de credenciais padrão. Para obter mais informações, consulte Usar uma função do IAM para conceder permissões para aplicações em execução em instâncias do Amazon EC2.

Se as credenciais do perfil da instância estiverem disponíveis, o construtor do cliente padrão criará uma instância da classe InstanceProfileCredentialsProvider do AWS SDK. A AWS usa essa classe para assinar solicitações de API com credenciais da AWS usando as credenciais de segurança temporárias dos metadados de instâncias do Amazon EC2.

Importante: se a aplicação usar a classe AWS SDK ProfileCredentialsProvider para fornecer credenciais temporárias da AWS, você será responsável por verificar e atualizar as credenciais antes que elas expirem. Não verificar ou atualizar suas credenciais aumenta a probabilidade de falhas nas aplicações causadas por erros de ExpiredToken.

Resolução

Use o Amazon Time Sync Service ou fontes de NTP

Configure o Amazon Time Sync Service ou outra fonte do Network Time Protocol (NTP) em sua instância do Amazon EC2. Assim, você garante que a instância do Linux tenha uma referência de horário consistente e precisa. Para obter mais informações, consulte Definir a hora para sua instância do Linux ou Definir a hora para uma instância do Windows.

Use credenciais temporárias personalizadas da AWS

Atualize as credenciais temporárias cinco minutos antes do vencimento.

Use uma função do IAM atribuída a uma instância

Anexe um perfil da instância à instância. Para obter mais informações, consulte Usar uma função do IAM para conceder permissões para aplicações em execução em instâncias do Amazon EC2. Verifique se não há outras credenciais especificadas no código ou na instância. As credenciais do perfil de instância são o último local consultado pela cadeia-padrão do provedor de credenciais. Caso existam credenciais localizadas em um local anterior da cadeia de pesquisa, elas impedirão que o IAM seja usado. Para obter mais informações, consulte Trabalho com credenciais da AWS.

Para ver as credenciais da AWS para uma função do IAM anexada a uma instância, execute os seguintes comandos de um shell do Linux ou do Windows PowerShell (v3.0 ou posterior). Certifique-se de substituir examplerole pelo nome da função do IAM.

Linux

Use o comando curl para ver as credenciais da AWS:

$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/examplerole

Esse comando retorna uma saída semelhante à seguinte:

{
    "Code" : "Success",
    "LastUpdated" : "2016-04-26T16:39:16Z",
    "Type" : "AWS-HMAC",
    "AccessKeyId" : "AKIAIOSFODNN7EXAMPLE",
    "SecretAccessKey" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
    "Token" : "token",
    "Expiration" : "2016-04-27T22:39:16Z"
}

Observação: se a execução do comando curl anterior retornar um erro 404, verifique o seguinte:

1.    Use o seguinte comando para verificar se o proxy HTTP está desabilitado para o endereço IP dos metadados:

$ export NO_PROXY=169.254.169.254

2.    Confirme se a instância não está fazendo várias solicitações ao mesmo tempo e executando mais de uma sessão simultaneamente. Caso isso esteja ocorrendo, o Instance Metadata Service (IMDS) poderá acionar o controle de utilização. Para resolver isso, use o cache e novas tentativas com o recuo exponencial. Assim como em outros serviços, as chamadas podem falhar. É recomendado realizar novas tentativas quando isso ocorrer. Para obter mais informações, consulte controle de utilização de consulta.

Para implementar novas tentativas, modifique AWS_METADATA_SERVICE_NUM_ATTENTS. Você pode definir opções usando variáveis de ambiente, no arquivo~/.aws/config ou na sessão botocore do usuário. Para obter mais informações, consulte Configuração na documentação do Boto3 DOCS 1.17.6.

Exemplo:

AWS_METADATA_SERVICE_TIMEOUT = 10
AWS_METADATA_SERVICE_NUM_ATTEMPTS = 5

3.    Se você estiver executando o teste curl em um contêiner docker, ajuste instance-metadata-options http-put-response-hop-limit:

$ aws ec2 modify-instance-metadata-options --instance-id $(curl 169.254.169.254/latest/meta-data/instance-id) --http-put-response-hop-limit 2 --http-endpoint enabled
PS C:\> Invoke-RestMethod http://169.254.169.254/latest/meta-data/iam/security-credentials/examplerole

Esse comando retorna uma saída semelhante à seguinte:

Code            : Success
LastUpdated     : 2016-07-18T18:09:47Z
Type            : AWS-HMAC
AccessKeyId     : AKIAIOSFODNN7EXAMPLE
SecretAccessKey : wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Token           : token
Expiration      : 2016-04-27T22:39:16Z

Use esses comandos para verificar as credenciais temporárias mais recentes da instância. Essas credenciais são alternadas ou atualizadas automaticamente cerca de cinco minutos antes da expiração das credenciais temporárias atribuídas.

Informações relacionadas

Trabalho com credenciais da AWS (AWS SDK for Java)

Uso de credenciais (AWS SDK for Java 2.0)

Funções do IAM para o Amazon EC2

Configuração de funções do IAM para o Amazon EC2 (avançado)


Este artigo ajudou?


Precisa de ajuda com faturamento ou suporte técnico?