Autenticación Básica
Middleware que proporciona soporte para Basic Auth.
Introducción a Basic Auth
Basic Auth es un mecanismo simple de autenticación HTTP que transmite credenciales a través del encabezado Authorization
en las solicitudes HTTP. El formato es Authorization: Basic <base64(username:password)>
. Aunque sencillo, como las credenciales solo están codificadas en Base64 y no encriptadas, generalmente debe usarse con HTTPS para garantizar la seguridad.
Comparación de implementaciones de Basic Auth en frameworks comunes
Framework | Lenguaje | Implementación de Basic Auth |
---|
Salvo | Rust | Mediante middleware BasicAuth e implementación personalizada de BasicAuthValidator |
Express | JavaScript | Usando el paquete middleware express-basic-auth |
Spring Security | Java | Configuración con httpBasic() e implementación de UserDetailsService |
ASP.NET Core | C# | Usando .UseAuthentication() y AddAuthentication(AuthenticationSchemes.Basic) |
Gin | Go | A través de middleware personalizado o usando el paquete gin-contrib/auth |
Casos de uso
Basic Auth es adecuado para los siguientes escenarios:
- APIs y herramientas internas: Herramientas administrativas y APIs de uso interno en empresas
- Entornos de desarrollo y pruebas: Implementación rápida de autenticación sin sistemas de login complejos
- Protección simple de APIs: Cuando no se requiere un sistema complejo de gestión de usuarios
- En combinación con otras medidas de seguridad: Como parte de una arquitectura de seguridad multicapa
En Salvo, el middleware Basic Auth puede integrarse fácilmente en las rutas, permitiendo personalizar la lógica de validación implementando el trait BasicAuthValidator
, lo que lo hace muy flexible.
Consideraciones importantes
- Siempre usar con HTTPS para proteger la transmisión de credenciales
- No es adecuado para entornos de producción que manejen información sensible
- Considerar usar métodos de autenticación más seguros como JWT, OAuth, etc. para entornos de producción
basic-auth/src/main.rs
use salvo::basic_auth::{BasicAuth, BasicAuthValidator};
use salvo::prelude::*;
// Custom validator implementing BasicAuthValidator trait
struct Validator;
impl BasicAuthValidator for Validator {
// Validate username and password combination
async fn validate(&self, username: &str, password: &str, _depot: &mut Depot) -> bool {
username == "root" && password == "pwd"
}
}
// Simple handler that returns "Hello" for authenticated requests
#[handler]
async fn hello() -> &'static str {
"Hello"
}
// Create router with basic authentication middleware
fn route() -> Router {
// Initialize basic authentication handler with our validator
let auth_handler = BasicAuth::new(Validator);
// Apply authentication middleware to the router
Router::with_hoop(auth_handler).goal(hello)
}
#[tokio::main]
async fn main() {
// Initialize logging
tracing_subscriber::fmt().init();
// Bind server to port 5800 and start serving
let acceptor = TcpListener::new("0.0.0.0:5800").bind().await;
Server::new(acceptor).serve(route()).await;
}
#[cfg(test)]
mod tests {
use salvo::prelude::*;
use salvo::test::{ResponseExt, TestClient};
#[tokio::test]
async fn test_basic_auth() {
// Create a service instance from our router for testing purposes
let service = Service::new(super::route());
// Test case 1: Verify successful authentication with valid credentials
let content = TestClient::get("http://0.0.0.0:5800/")
.basic_auth("root", Some("pwd")) // Use correct username/password
.send(&service) // Send the request to the service
.await
.take_string() // Extract response body as string
.await
.unwrap();
// Verify response contains expected "Hello" message
assert!(content.contains("Hello"));
// Test case 2: Verify authentication failure with invalid password
let content = TestClient::get("http://0.0.0.0:5800/")
.basic_auth("root", Some("pwd2")) // Use incorrect password
.send(&service) // Send the request to the service
.await
.take_string() // Extract response body as string
.await
.unwrap();
// Verify response contains "Unauthorized" error
assert!(content.contains("Unauthorized"));
}
}