Como Implementar autenticação básica em uma página estática usando AWS Cloudfront e Lambda@Edge

como implementar autenticação básica em uma pagina

PopUp de autenticação básica

Às vezes, precisamos de uma solução rápida e simples para adicionar uma camada de autenticação básica em uma página estática servida pelo CloudFront. Essa solução pode ser útil para restringir o acesso de maneira rápida sem a necessidade de uma implementação mais complexa.

A autenticação básica utiliza um cabeçalho HTTP específico chamado Authorization, que combina um nome de usuário e uma senha codificados em Base64. O CloudFront, juntamente com uma função Lambda@Edge, oferece uma maneira eficiente de implementar essa lógica.

A autenticação básica no HTTP segue o formato:
				
					Authorization: Basic <base64(nome_de_usuário:senha)>
				
			
Por exemplo, se tivermos o seguinte nome de usuário e senha:

  • Nome de usuário: user
  • Senha: securePassword@123
O cabeçalho Authorization deve ser codificado da seguinte forma:

				
					Authorization: Basic dXNlcjpzZWN1cmVQYXNzd29yZEAxMjM=
				
			

Essa string Base64 é o resultado da codificação de ‘user:securePassword@123’.

Validando a Autenticação no CloudFront

Quando uma solicitação é recebida pelo CloudFront, queremos garantir que a autorização fornecida pelo solicitante corresponde à nossa configuração preferida. Podemos fazer isso de duas maneiras:

  1. Comparar a string Base64 diretamente: Codificamos nosso nome de usuário e senha preferidos em Base64 e comparamos com o valor enviado pelo cliente.
  2. Decodificar a string Base64 enviada e extrair as credenciais: Essa abordagem permite uma verificação mais flexível, mas não é necessária para a maioria dos casos simples.

Implementando a Solução com Lambda@Edge

O AWS CloudFront nos permite associar uma função Lambda a quatro pontos diferentes de execução, chamados de triggers:

  1. Viewer Request: Quando o CloudFront recebe a solicitação do usuário final.
  2. Origin Request: Quando o CloudFront está prestes a enviar a solicitação para a origem, como um bucket S3.
  3. Origin Response: Quando o CloudFront recebe a resposta da origem.
  4. Viewer Response: Quando o CloudFront está prestes a enviar a resposta para o usuário final.

Para o nosso caso, queremos implementar a lógica de autenticação no ponto Viewer Request, porque é nesse momento que precisamos validar a autorização antes de qualquer outra etapa do processamento da solicitação.

Código de Exemplo em Python

Aqui está um exemplo de código Python para uma função Lambda@Edge que valida a autenticação básica:

				
					import base64

def lambda_handler(event, context):
    # Verifica se o evento contém os registros esperados
    if not event.get('Records'):
        return {
            "status": "400",
            "statusDescription": "Bad Request",
            "body": "Invalid event structure."
        }
    
    try:
        # Obtenha o cabeçalho de autenticação do evento do CloudFront
        headers = event['Records'][0].get('cf', {}).get('request', {}).get('headers', {})
        authorization_header = headers.get('authorization', [{}])[0].get('value', '')

        # Define a autenticação preferida em Base64
        username = "user"
        password = "securePassword@123"
        preferred_authorization = f"Basic {base64.b64encode(f'{username}:{password}'.encode()).decode()}"

        # Verifique se o cabeçalho de autenticação corresponde ao valor preferido
        if authorization_header == preferred_authorization:
            # Permita que a solicitação prossiga para o CloudFront
            return event['Records'][0]['cf']['request']
        
        # Se a autenticação falhar, retorna uma resposta 401 (Não autorizado)
        return {
            "status": "401",
            "statusDescription": "Unauthorized",
            "headers": {
                "www-authenticate": [{"key": "WWW-Authenticate", "value": 'Basic realm="Enter your credentials"'}]
            }
        }

    except Exception as e:
        # Tratamento de erro genérico
        return {
            "status": "500",
            "statusDescription": "Internal Server Error",
            "body": f"An unexpected error occurred: {str(e)}"
        } 
				
			

Explicação do Código

  1. Captura do Cabeçalho de Autenticação: O código extrai o cabeçalho Authorization da solicitação. Essa é a parte crucial que contém as credenciais codificadas em Base64.
  2. Comparação da String Base64: A função codifica o nome de usuário e a senha preferidos e compara com o valor recebido. Se corresponder, a solicitação é permitida.
  3. Resposta HTTP 401 (Unauthorized): Se as credenciais não forem válidas, o Lambda retorna uma resposta 401, que geralmente aciona o navegador para solicitar as credenciais.
  4. Respostas a Erros: A função lida com erros inesperados e retorna uma mensagem apropriada.

Configurando o Lambda@Edge no CloudFront

  1. Crie a função Lambda no console da AWS.
  2. Defina o handler como lambda_function.lambda_handler.
  3. Associe a função ao trigger Viewer Request no CloudFront.
  4. Certifique-se de publicar uma versão específica da função (o ARN deve terminar com um número de versão, como :1).

Considerações Finais

Essa solução é ideal para adicionar uma camada simples de autenticação para proteger conteúdos estáticos ou ambientes de teste. No entanto, é importante lembrar que a autenticação básica não é a solução mais segura para cenários críticos, já que as credenciais são facilmente decodificáveis. Considere métodos mais avançados, como OAuth ou autenticação baseada em tokens, para ambientes de produção.

Essa abordagem com Lambda@Edge oferece flexibilidade e eficiência ao integrar lógica personalizada diretamente na borda da rede da AWS, garantindo performance e segurança.

Espero que esse guia tenha sido útil! Se precisar de mais detalhes ou tiver alguma dúvida, estou à disposição.

Referências

Gostou do artigo? Não se esqueça de curtir e compartilhar o artigo para ajudar mais pessoas com dúvidas em tecnologia.

Como Implementar autenticação básica em uma página estática usando AWS Cloudfront e Lambda@Edge

como implementar autenticação básica em uma pagina

PopUp de autenticação básica

Às vezes, precisamos de uma solução rápida e simples para adicionar uma camada de autenticação básica em uma página estática servida pelo CloudFront. Essa solução pode ser útil para restringir o acesso de maneira rápida sem a necessidade de uma implementação mais complexa.

A autenticação básica utiliza um cabeçalho HTTP específico chamado Authorization, que combina um nome de usuário e uma senha codificados em Base64. O CloudFront, juntamente com uma função Lambda@Edge, oferece uma maneira eficiente de implementar essa lógica.

A autenticação básica no HTTP segue o formato:
				
					Authorization: Basic <base64(nome_de_usuário:senha)>
				
			
Por exemplo, se tivermos o seguinte nome de usuário e senha:

  • Nome de usuário: user
  • Senha: securePassword@123
O cabeçalho Authorization deve ser codificado da seguinte forma:

				
					Authorization: Basic dXNlcjpzZWN1cmVQYXNzd29yZEAxMjM=
				
			

Essa string Base64 é o resultado da codificação de ‘user:securePassword@123’.

Validando a Autenticação no CloudFront

Quando uma solicitação é recebida pelo CloudFront, queremos garantir que a autorização fornecida pelo solicitante corresponde à nossa configuração preferida. Podemos fazer isso de duas maneiras:

  1. Comparar a string Base64 diretamente: Codificamos nosso nome de usuário e senha preferidos em Base64 e comparamos com o valor enviado pelo cliente.
  2. Decodificar a string Base64 enviada e extrair as credenciais: Essa abordagem permite uma verificação mais flexível, mas não é necessária para a maioria dos casos simples.

Implementando a Solução com Lambda@Edge

O AWS CloudFront nos permite associar uma função Lambda a quatro pontos diferentes de execução, chamados de triggers:

  1. Viewer Request: Quando o CloudFront recebe a solicitação do usuário final.
  2. Origin Request: Quando o CloudFront está prestes a enviar a solicitação para a origem, como um bucket S3.
  3. Origin Response: Quando o CloudFront recebe a resposta da origem.
  4. Viewer Response: Quando o CloudFront está prestes a enviar a resposta para o usuário final.

Para o nosso caso, queremos implementar a lógica de autenticação no ponto Viewer Request, porque é nesse momento que precisamos validar a autorização antes de qualquer outra etapa do processamento da solicitação.

Código de Exemplo em Python

Aqui está um exemplo de código Python para uma função Lambda@Edge que valida a autenticação básica:

				
					import base64

def lambda_handler(event, context):
    # Verifica se o evento contém os registros esperados
    if not event.get('Records'):
        return {
            "status": "400",
            "statusDescription": "Bad Request",
            "body": "Invalid event structure."
        }
    
    try:
        # Obtenha o cabeçalho de autenticação do evento do CloudFront
        headers = event['Records'][0].get('cf', {}).get('request', {}).get('headers', {})
        authorization_header = headers.get('authorization', [{}])[0].get('value', '')

        # Define a autenticação preferida em Base64
        username = "user"
        password = "securePassword@123"
        preferred_authorization = f"Basic {base64.b64encode(f'{username}:{password}'.encode()).decode()}"

        # Verifique se o cabeçalho de autenticação corresponde ao valor preferido
        if authorization_header == preferred_authorization:
            # Permita que a solicitação prossiga para o CloudFront
            return event['Records'][0]['cf']['request']
        
        # Se a autenticação falhar, retorna uma resposta 401 (Não autorizado)
        return {
            "status": "401",
            "statusDescription": "Unauthorized",
            "headers": {
                "www-authenticate": [{"key": "WWW-Authenticate", "value": 'Basic realm="Enter your credentials"'}]
            }
        }

    except Exception as e:
        # Tratamento de erro genérico
        return {
            "status": "500",
            "statusDescription": "Internal Server Error",
            "body": f"An unexpected error occurred: {str(e)}"
        } 
				
			

Explicação do Código

  1. Captura do Cabeçalho de Autenticação: O código extrai o cabeçalho Authorization da solicitação. Essa é a parte crucial que contém as credenciais codificadas em Base64.
  2. Comparação da String Base64: A função codifica o nome de usuário e a senha preferidos e compara com o valor recebido. Se corresponder, a solicitação é permitida.
  3. Resposta HTTP 401 (Unauthorized): Se as credenciais não forem válidas, o Lambda retorna uma resposta 401, que geralmente aciona o navegador para solicitar as credenciais.
  4. Respostas a Erros: A função lida com erros inesperados e retorna uma mensagem apropriada.

Configurando o Lambda@Edge no CloudFront

  1. Crie a função Lambda no console da AWS.
  2. Defina o handler como lambda_function.lambda_handler.
  3. Associe a função ao trigger Viewer Request no CloudFront.
  4. Certifique-se de publicar uma versão específica da função (o ARN deve terminar com um número de versão, como :1).

Considerações Finais

Essa solução é ideal para adicionar uma camada simples de autenticação para proteger conteúdos estáticos ou ambientes de teste. No entanto, é importante lembrar que a autenticação básica não é a solução mais segura para cenários críticos, já que as credenciais são facilmente decodificáveis. Considere métodos mais avançados, como OAuth ou autenticação baseada em tokens, para ambientes de produção.

Essa abordagem com Lambda@Edge oferece flexibilidade e eficiência ao integrar lógica personalizada diretamente na borda da rede da AWS, garantindo performance e segurança.

Espero que esse guia tenha sido útil! Se precisar de mais detalhes ou tiver alguma dúvida, estou à disposição.

Referências

Gostou do artigo? Não se esqueça de curtir e compartilhar o artigo para ajudar mais pessoas com dúvidas em tecnologia.