Introducción
En los sistemas distribuidos, la seguridad es un aspecto crítico que debe ser gestionado con cuidado. Dos de los componentes más importantes de la seguridad son la autenticación y la autorización. Este tema se centrará en explicar estos conceptos, sus diferencias, y cómo se implementan en sistemas distribuidos.
Conceptos Básicos
Autenticación
La autenticación es el proceso de verificar la identidad de un usuario o sistema. En otras palabras, es el mecanismo que asegura que una entidad es quien dice ser.
Métodos Comunes de Autenticación:
- Contraseñas: El método más común, donde el usuario proporciona un nombre de usuario y una contraseña.
- Tokens: Utilizan tokens generados por sistemas de autenticación como OAuth.
- Certificados Digitales: Utilizan certificados emitidos por una autoridad de certificación (CA).
- Biometría: Utilizan características físicas como huellas dactilares o reconocimiento facial.
Autorización
La autorización es el proceso de determinar si una entidad autenticada tiene permiso para realizar una acción específica. Es el mecanismo que controla el acceso a recursos y operaciones.
Métodos Comunes de Autorización:
- Listas de Control de Acceso (ACL): Especifican qué usuarios o sistemas tienen acceso a qué recursos.
- Roles y Políticas: Utilizan roles y políticas para definir permisos de acceso.
- OAuth: Un protocolo de autorización que permite a las aplicaciones obtener acceso limitado a los recursos de un usuario.
Ejemplo Práctico
Autenticación con JWT (JSON Web Tokens)
Los JWT son una forma popular de manejar la autenticación en sistemas distribuidos. A continuación, se muestra un ejemplo de cómo se puede implementar la autenticación con JWT en una aplicación web.
Paso 1: Generar un Token JWT
import jwt import datetime # Clave secreta para firmar el token SECRET_KEY = 'mi_clave_secreta' def generar_token(usuario_id): payload = { 'user_id': usuario_id, 'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1) } token = jwt.encode(payload, SECRET_KEY, algorithm='HS256') return token # Generar un token para el usuario con ID 123 token = generar_token(123) print(token)
Paso 2: Verificar un Token JWT
def verificar_token(token): try: payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256']) return payload['user_id'] except jwt.ExpiredSignatureError: return 'Token expirado' except jwt.InvalidTokenError: return 'Token inválido' # Verificar el token generado anteriormente usuario_id = verificar_token(token) print(usuario_id)
Autorización con Roles
A continuación, se muestra un ejemplo de cómo se puede implementar la autorización basada en roles en una aplicación web.
Paso 1: Definir Roles y Permisos
roles_permisos = { 'admin': ['leer', 'escribir', 'borrar'], 'usuario': ['leer'] } def tiene_permiso(rol, permiso): return permiso in roles_permisos.get(rol, [])
Paso 2: Verificar Permisos
# Verificar si un usuario con rol 'admin' tiene permiso para 'borrar' rol = 'admin' permiso = 'borrar' if tiene_permiso(rol, permiso): print(f"El rol {rol} tiene permiso para {permiso}") else: print(f"El rol {rol} NO tiene permiso para {permiso}")
Ejercicios Prácticos
Ejercicio 1: Implementar Autenticación con JWT
- Objetivo: Implementar una función para generar y verificar tokens JWT.
- Instrucciones:
- Escribe una función
generar_token(usuario_id)
que genere un token JWT para un usuario dado. - Escribe una función
verificar_token(token)
que verifique un token JWT y devuelva el ID del usuario si el token es válido.
- Escribe una función
Ejercicio 2: Implementar Autorización Basada en Roles
- Objetivo: Implementar una función para verificar permisos basados en roles.
- Instrucciones:
- Define un diccionario
roles_permisos
que asigne roles a permisos. - Escribe una función
tiene_permiso(rol, permiso)
que verifique si un rol dado tiene un permiso específico.
- Define un diccionario
Soluciones
Solución al Ejercicio 1
import jwt import datetime SECRET_KEY = 'mi_clave_secreta' def generar_token(usuario_id): payload = { 'user_id': usuario_id, 'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1) } token = jwt.encode(payload, SECRET_KEY, algorithm='HS256') return token def verificar_token(token): try: payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256']) return payload['user_id'] except jwt.ExpiredSignatureError: return 'Token expirado' except jwt.InvalidTokenError: return 'Token inválido' # Prueba de las funciones token = generar_token(123) print(token) usuario_id = verificar_token(token) print(usuario_id)
Solución al Ejercicio 2
roles_permisos = { 'admin': ['leer', 'escribir', 'borrar'], 'usuario': ['leer'] } def tiene_permiso(rol, permiso): return permiso in roles_permisos.get(rol, []) # Prueba de la función rol = 'admin' permiso = 'borrar' if tiene_permiso(rol, permiso): print(f"El rol {rol} tiene permiso para {permiso}") else: print(f"El rol {rol} NO tiene permiso para {permiso}")
Conclusión
En esta sección, hemos cubierto los conceptos básicos de autenticación y autorización en sistemas distribuidos. Hemos aprendido sobre diferentes métodos de autenticación y autorización, y hemos visto ejemplos prácticos de cómo implementar estos conceptos utilizando JWT y roles. Estos fundamentos son cruciales para asegurar que los sistemas distribuidos sean seguros y que el acceso a los recursos esté adecuadamente controlado.
Curso de Arquitecturas Distribuidas
Módulo 1: Introducción a los Sistemas Distribuidos
- Conceptos Básicos de Sistemas Distribuidos
- Modelos de Sistemas Distribuidos
- Ventajas y Desafíos de los Sistemas Distribuidos