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:

  1. Contraseñas: El método más común, donde el usuario proporciona un nombre de usuario y una contraseña.
  2. Tokens: Utilizan tokens generados por sistemas de autenticación como OAuth.
  3. Certificados Digitales: Utilizan certificados emitidos por una autoridad de certificación (CA).
  4. 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:

  1. Listas de Control de Acceso (ACL): Especifican qué usuarios o sistemas tienen acceso a qué recursos.
  2. Roles y Políticas: Utilizan roles y políticas para definir permisos de acceso.
  3. 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

  1. Objetivo: Implementar una función para generar y verificar tokens JWT.
  2. 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.

Ejercicio 2: Implementar Autorización Basada en Roles

  1. Objetivo: Implementar una función para verificar permisos basados en roles.
  2. 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.

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.

© Copyright 2024. Todos los derechos reservados