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_permisosque 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
