Saltar al contenido

Seguridad: OAuth y JWT

Cómo se protege una API que no guarda sesión: TLS para el canal, HTTP Basic, OAuth 2.0 para delegar la autorización, y JWT con su estructura y sus claims.

El panorama: qué protege cada pieza

REST no trae seguridad propia: no forma parte del estilo. Lo que se hace es combinar mecanismos que ya existen en HTTP y alrededor de HTTP, y lo primero es tener claro qué resuelve cada uno, porque el examen mezcla las columnas.

MecanismoQué aporta
TLSConfidencialidad e integridad del canal, y autenticación del servidor
HTTP BasicAutenticación del cliente enviando usuario y contraseña codificados
OAuth 2.0Autorización delegada: dar acceso a un tercero sin entregarle la contraseña
JWTFormato de testigo que transporta de forma verificable la identidad y los permisos

HTTP Basic merece un aviso: las credenciales van codificadas en base64, que no es cifrado sino una simple representación en texto. Cualquiera que vea el tráfico las lee, así que Basic sin TLS por debajo equivale a enviar la contraseña en claro.

Los mecanismos se acumulan, no se eligen: TLS protege el canal y por dentro viaja el testigo que identifica y autoriza. Uno no sustituye al otro.

Para el examen

  • Qué protege TLS: el canal: confidencialidad, integridad y autenticación del servidor

  • Qué viaja por dentro: el testigo que identifica y autoriza

  • HTTP Basic sin TLS: no vale: base64 no es cifrado

OAuth 2.0 y el esquema Bearer

OAuth 2.0 resuelve un problema concreto: que una aplicación pueda acceder a los recursos de un usuario en otro servicio sin conocer su contraseña. El usuario se autentica ante el proveedor, este emite un testigo de acceso limitado en alcance y en tiempo, y la aplicación presenta ese testigo en cada llamada.

Conviene decirlo con precisión porque es la trampa habitual: OAuth 2.0 es un marco de autorización delegada, no un protocolo de autenticación. Quien añade la autenticación de usuarios sobre él es OpenID Connect, que es una capa construida encima.

El testigo se envía en la cabecera Authorization con el esquema Bearer, que significa literalmente «al portador»: quien lo lleva, lo usa. De ahí que un testigo Bearer robado sirva a quien lo roba, y de ahí que TLS no sea opcional.

http
GET /api/alumnos/482/falladas HTTP/1.1
Host: api.llegandoalcorte.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0ODIi...
Accept: application/json

OAuth 2.0 autoriza, no autentica. Si una pregunta define OAuth como «autenticación basada en token», está describiendo el uso corriente, no el estándar.

Para el examen

  • Qué hace: AUTORIZA, no autentica

  • Qué permite: que una aplicación acceda a recursos del usuario sin conocer su contraseña

  • Cómo: con un testigo de alcance y duración limitados

  • Esquema de presentación: Bearer

JWT: estructura y firma

JWT (JSON Web Token) es un formato de testigo compacto, pensado para viajar en una cabecera HTTP. Tiene tres partes separadas por puntos: cabecera, carga y firma. Cada una es un objeto JSON codificado en base64, salvo la firma, que es el resultado del cálculo criptográfico.

texto
cabecera . carga . firma

cabecera   { "alg": "HS256", "typ": "JWT" }

carga      { "sub": "482",
             "iat": 1786000000,
             "exp": 1786003600,
             "plan": "largo" }

firma      HMAC-SHA256(
             base64url(cabecera) + "." + base64url(carga),
             clave secreta que solo conoce el servidor )

La cabecera declara el algoritmo con el que se ha firmado. El servidor calcula la firma sobre la cabecera y la carga usando una clave que solo él conoce, y al recibir el testigo repite el cálculo: si coincide, el contenido no se ha tocado. Así puede confiar en el testigo sin haber guardado nada, que es justo lo que necesita un servicio sin estado.

La carga está codificada, no cifrada: cualquiera puede leerla. La firma impide modificarla, no impide verla, así que en un JWT no se meten datos sensibles.

Para el examen

  • Sus tres partes: cabecera, carga y firma, separadas por puntos

  • Cómo va la carga: codificada en base64, NO cifrada

  • Consecuencia: cualquiera puede leerla: no se meten datos sensibles

Los claims y la ausencia de sesión

Los datos que van en la carga de un JWT se llaman claims: afirmaciones sobre el sujeto del testigo. Unos están registrados y significan lo mismo en todas partes, y otros los define la aplicación para sus propias necesidades, como el plan contratado o el papel del usuario.

ClaimSignificado
subSujeto: a quién se refiere el testigo
iatMomento en que se emitió
expMomento a partir del cual deja de aceptarse

Como el servicio no guarda sesión, el cliente tiene que enviar el testigo en todas y cada una de las peticiones: no hay nada al otro lado que recuerde que ya se identificó hace un minuto. Esa es la consecuencia práctica más visible de que REST sea sin estado, y también su punto débil, porque un testigo emitido no se puede retirar antes de que expire salvo que se monte una lista de revocación, que es precisamente volver a guardar estado.

Para el examen

  • Qué son los claims: las afirmaciones de la carga

  • sub, iat y exp: sujeto, fecha de emisión y caducidad

  • Su punto débil: no se puede revocar antes de expirar

  • El remedio y su precio: una lista de revocación, que es volver a guardar estado