
PopUp de autenticação básica
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
- Nome de usuário: user
- Senha: securePassword@123
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:
- Comparar a string Base64 diretamente: Codificamos nosso nome de usuário e senha preferidos em Base64 e comparamos com o valor enviado pelo cliente.
- 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:
- Viewer Request: Quando o CloudFront recebe a solicitação do usuário final.
- Origin Request: Quando o CloudFront está prestes a enviar a solicitação para a origem, como um bucket S3.
- Origin Response: Quando o CloudFront recebe a resposta da origem.
- 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
- 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.
- 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.
- 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.
- Respostas a Erros: A função lida com erros inesperados e retorna uma mensagem apropriada.
Configurando o Lambda@Edge no CloudFront
- Crie a função Lambda no console da AWS.
- Defina o handler como lambda_function.lambda_handler.
- Associe a função ao trigger Viewer Request no CloudFront.
- 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