¿Qué es un token?
Antes de introducir los tokens opacos, es importante entender qué es un token:
Los tokens se utilizan para representar y transmitir información segura entre partes, y soportan la gran mayoría de los procesos de Autenticación (Authentication) y Autorización (Authorization) que ocurren en internet detrás de escena. Los dos tipos más populares de tokens en servicios web son JSON Web Token (JWT) y tokens opacos.
¿Qué es un token opaco?
Los tokens opacos son tokens en un formato propietario al que no puedes acceder y típicamente contienen algún identificador para información en el almacenamiento persistente de un servidor.
Un token opaco es una forma que puede tomar un token, y los access tokens y los refresh tokens pueden existir como tokens opacos. El formato de un token opaco es determinado por su issuer (emisor), y típicamente es una cadena de números y/o caracteres utilizada para ayudar al issuer (emisor) a recuperar e identificar cierta información en una base de datos. Aquí hay un ejemplo de un token opaco:
M-oxIny1RfaFbmjMX54L8Pl-KQEPeQvF6awzjWFA3iq
Por otro lado, JWT es otro formato común de token. Es una cadena JSON que contiene todos los claims (reclamaciones) e información, junto con una firma del issuer (emisor). Por defecto, no está encriptado, aunque puede ser encriptado usando el estándar Cifrado Web JSON (JSON Web Encryption, JWE) . Aunque JWT típicamente no está encriptado, no compromete su seguridad: la presencia de la firma asegura la integridad del contenido del token, permitiendo plena confianza en los datos dentro del JWT.
A diferencia de JWT, que contiene toda la información necesaria para ser validado directamente en el recurso protegido, los tokens opacos no pueden ser validados directamente por el recurso. En su lugar, requieren validación por el issuer (emisor) del token opaco (usualmente el Servidor de autorización (Authorization server) ). Este proceso de validación se refiere típicamente como Análisis de token (Token introspection) .
¿Qué es JWT?
En contraste con los tokens opacos, un JWT es un token autónomo y sin estado que lleva información en un formato estructurado y legible.
Un JWT se compone de tres partes: un header
, un payload
y una signature
, cada uno codificado en Base64URL.
Aquí hay un ejemplo de un JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- El
header
contiene información sobre el tipo de token y el algoritmo usado para firmar. Por ejemplo,{"alg": "HS256", "typ": "JWT"}
. - La sección
payload
contiene claims (reclamaciones): piezas de información sobre el usuario o la autorización, como el ID del usuario, el tiempo de expiración y los scopes (alcances). Debido a que estos datos están codificados pero no encriptados, cualquiera que tenga el token puede decodificarlo para ver los claims, aunque no puede alterarlo sin invalidar la firma. Basado en la especificación y la configuración del authorization server, varios claims pueden ser incluidos en el payload. Esto le da al token su naturaleza autónoma. Por ejemplo,{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
. - La
signature
se genera combinando el header, el payload y una clave secreta usando el algoritmo especificado. Esta firma se utiliza para verificar la integridad del token y asegurar que no ha sido manipulado.
Los JWTs son comúnmente usados porque pueden ser verificados localmente por el cliente o cualquier servicio, sin necesidad de interactuar con el authorization server. Esto hace que los JWTs sean particularmente eficientes para sistemas distribuidos, donde múltiples servicios podrían necesitar verificar la autenticidad del token de manera independiente.
Sin embargo, esta conveniencia también viene con la responsabilidad de asegurar que los claims del token no estén excesivamente expuestos, ya que son visibles para cualquiera que tenga acceso al token. Además, los JWTs son típicamente de corta duración, y el tiempo de expiración está incluido en los claims del token para asegurar que el token no sea válido indefinidamente.
Validación de access token opaco
Un access token opaco se valida enviándolo de vuelta al authorization server para su verificación. El authorization server mantiene el estado de los tokens emitidos y puede determinar la validez del token basado en su almacenamiento interno.
- El cliente solicita un access token al authorization server.
- El authorization server emite un token opaco.
- El cliente envía la solicitud de acceso al recurso con el token opaco en el encabezado.
- El proveedor de recursos envía una solicitud de introspección del token al authorization server para validar el token.
- El authorization server responde con la información del token.
Validación de access token JWT (offline)
Un access token JWT puede ser validado offline por el cliente o cualquier servicio que tenga acceso a la clave pública del token.
- El proveedor de recursos preobtiene la clave pública del authorization server desde el Descubrimiento de OpenID Connect (OpenID Connect Discovery) . La clave pública se utiliza para verificar la firma del token y asegurar su integridad.
- El cliente solicita un access token al authorization server.
- El authorization server emite un token JWT.
- El cliente envía la solicitud de acceso al recurso con el token JWT en el encabezado.
- El proveedor de recursos decodifica y valida el token JWT usando la clave pública obtenida del authorization server.
- El proveedor de recursos concede acceso basado en la validez del token.
Casos de uso en OIDC
En el contexto de OIDC ( OpenID Connect (OIDC) ), los tokens opacos y los JWTs sirven para diferentes propósitos y se utilizan en escenarios distintos.
Tokens opacos
- Recuperación de perfil de usuario:
Por defecto, cuando un cliente solicita un access token sin especificar un recurso e incluye el scope openid
, el authorization server emite un access token opaco. Este token se utiliza principalmente para recuperar información del perfil de usuario desde el endpoint /oidc/userinfo
de OIDC. Al recibir una solicitud con el access token opaco, el authorization server verifica su almacenamiento interno para recuperar la información de autorización asociada y verifica la validez del token antes de responder con los detalles del perfil de usuario.
- Intercambio de refresh token:
Los refresh tokens están diseñados para ser intercambiados solo entre el cliente y el authorization server, sin necesidad de ser compartidos con los proveedores de recursos. Como tal, los refresh tokens son típicamente emitidos como tokens opacos. Cuando el access token actual expira, el cliente puede usar el refresh token opaco para obtener un nuevo access token, asegurando acceso continuo sin volver a autenticar al usuario.
JWTs
- ID token:
En OIDC, el ID token es un JWT que contiene información del usuario y se utiliza para autenticar al usuario. Típicamente emitido junto con el access token, el ID token permite al cliente verificar la identidad del usuario. Por ejemplo:
// Payload decodificado de un ID token
{
"iss": "<https://auth.wiki>",
"sub": "1234567890",
"aud": "client_id",
"exp": 1630368000,
"name": "John Doe",
"email": "[email protected]",
"picture": "<https://example.com/johndoe.jpg>"
}
El cliente puede validar el ID token para asegurar la identidad del usuario y extraer información del usuario para personalización o propósitos de autorización. El ID token es solo para uso único y no debe ser utilizado para la autorización de recursos de API.
- Acceso a recursos de API (usando access token):
Cuando un cliente solicita un access token con un Indicador de recursos (Resource indicator) específico, el authorization server emite un access token JWT destinado a acceder a ese recurso. El JWT contiene claims que el proveedor de recursos puede usar para autorizar el acceso del cliente. Por ejemplo:
// Payload decodificado de un access token JWT
{
"iss": "<https://auth.wiki>",
"sub": "1234567890",
"aud": "<https://api.example.com>",
"scope": "read write",
"exp": 1630368000
}
El proveedor de recursos puede validar la solicitud verificando los claims:
iss
: Confirma que el token fue emitido por un authorization server de confianza.sub
: Identifica al usuario asociado con el token.aud
: Asegura que el token está destinado al recurso específico.scope
: Verifica los permisos otorgados al usuario.