Abreviatura | JWT |
---|---|
Estado | Norma propuesta |
Primera publicación | 28 de diciembre de 2010 ( 28 de diciembre de 2010 ) |
Última versión | RFC 7519 Mayo de 2015 |
Organización | Federación Internacional de Fútbol Americano (IETF) |
Comité | IGSE |
Autores |
|
Normas básicas |
|
Dominio | Intercambio de datos |
Sitio web | datatracker.ietf.org/doc/html/rfc7519 |
JSON Web Token ( JWT , pronunciación sugerida / dʒɒt / , igual que la palabra "jot" [ 1] ) es un estándar de Internet propuesto para crear datos con firma opcional y/o cifrado opcional cuya carga útil contiene JSON que afirma una cierta cantidad de afirmaciones . Los tokens se firman utilizando un secreto privado o una clave pública/privada .
Por ejemplo, un servidor podría generar un token que tenga la afirmación "iniciado sesión como administrador" y proporcionársela a un cliente. El cliente podría entonces utilizar ese token para demostrar que ha iniciado sesión como administrador. Los tokens pueden estar firmados por la clave privada de una de las partes (normalmente la del servidor) de modo que cualquier parte pueda verificar posteriormente si el token es legítimo. Si la otra parte, por algún medio adecuado y fiable, está en posesión de la clave pública correspondiente, también podrá verificar la legitimidad del token. Los tokens están diseñados para ser compactos, [2] seguros para URL , [3] y utilizables, especialmente en un contexto de inicio de sesión único (SSO) de navegador web . Las afirmaciones JWT se pueden utilizar normalmente para pasar la identidad de usuarios autenticados entre un proveedor de identidad y un proveedor de servicios , o cualquier otro tipo de afirmaciones según lo requieran los procesos empresariales. [4] [5]
JWT se basa en otros estándares basados en JSON: JSON Web Signature y JSON Web Encryption . [1] [6] [7]
HS256
indica que este token está firmado con HMAC-SHA256.{ "alg" : "HS256" , "tipo" : "JWT" }
iat
) y un reclamo personalizado ( loggedInAs
).{ "loggedInAs" : "admin" , "iat" : 1422779638 }
HMAC_SHA256 ( secreto , base64urlEncoding ( encabezado ) + '.' + base64urlEncoding ( carga útil ) )
Las tres partes se codifican por separado utilizando Base64url Encoding RFC 4648 y se concatenan utilizando puntos para producir el JWT:
const token = base64urlEncoding ( encabezado ) + '.' + base64urlEncoding ( carga útil ) + '.' + base64urlEncoding ( firma )
Los datos anteriores y el secreto de "secretkey" crean el token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN
_oWnFSRgCzcmJmMjLiuyu5CSpyHI=
(Las cadenas json anteriores están formateadas sin nuevas líneas ni espacios, en matrices de bytes UTF-8. Esto es importante ya que incluso cambios leves en los datos afectarán el token resultante)
Este token resultante se puede pasar fácilmente a HTML y HTTP . [3]
En la autenticación, cuando un usuario inicia sesión correctamente, se suele devolver un token web JSON (JWT). Este token debe enviarse al cliente mediante un mecanismo seguro, como una cookie exclusiva de HTTP . No se recomienda almacenar el JWT localmente en mecanismos de almacenamiento del navegador, como el almacenamiento local o de sesión . Esto se debe a que JavaScript que se ejecuta en el lado del cliente (incluidas las extensiones del navegador) puede acceder a estos mecanismos de almacenamiento, lo que expone el JWT y compromete la seguridad. En el caso de procesos desatendidos, el cliente también puede autenticarse directamente generando y firmando su propio JWT con un secreto compartido previamente y pasándolo a un servicio compatible con OAuth de la siguiente manera:
POST /oauth2/token Tipo de contenido: aplicación / x-www-form-urlencoded tipo_concesión = urn:ietf:params:oauth:tipo-concesión:jwt-bearer & aserción = eyJhb...
Si el cliente pasa una aserción JWT válida, el servidor generará un access_token válido para realizar llamadas a la aplicación y lo pasará de vuelta al cliente:
{ "access_token" : "eyJhb..." , "token_type" : "Portador" , "expires_in" : 3600 }
Cuando el cliente desea acceder a una ruta o un recurso protegido, el agente de usuario debe enviar el JWT, normalmente en el Authorization
encabezado HTTP mediante el Bearer
esquema. El contenido del encabezado podría ser similar al siguiente:
Autorización: Portador eyJhbGci ...<snip>... yu5CSpyHI
Este es un mecanismo de autenticación sin estado, ya que el estado del usuario nunca se guarda en la memoria del servidor. Las rutas protegidas del servidor comprobarán si hay un JWT válido en el encabezado de autorización y, si está presente, se permitirá al usuario acceder a los recursos protegidos. Como los JWT son autónomos, toda la información necesaria está allí, lo que reduce la necesidad de consultar la base de datos varias veces.
Código | Nombre | Descripción |
---|---|---|
Campos de reclamación estándar | Los borradores de Internet definen los siguientes campos estándar ("reclamos") que pueden usarse dentro de un conjunto de reclamos JWT. | |
iss | Editor | Identifica al principal que emitió el JWT. |
sub | Sujeto | Identifica el sujeto del JWT. |
aud | Audiencia | Identifica los destinatarios a los que está destinado el JWT. Cada entidad principal que se supone que debe procesar el JWT debe identificarse con un valor en la declaración de audiencia. Si la entidad principal que procesa la declaración no se identifica con un valor en la aud declaración cuando esta está presente, entonces el JWT debe rechazarse. |
exp | Tiempo de expiración | Identifica el tiempo de expiración a partir del cual no se debe aceptar el JWT para su procesamiento. El valor debe ser un NumericDate: [9], ya sea un número entero o decimal, que represente los segundos después de 1970-01-01 00:00:00Z . |
nbf | No antes | Identifica la hora en la que se empezará a aceptar el JWT para su procesamiento. El valor debe ser una fecha numérica. |
iat | Emitido en | Identifica la hora en la que se emitió el JWT. El valor debe ser un NumericDate. |
jti | Identificación JWT | Identificador único del token que distingue entre mayúsculas y minúsculas, incluso entre diferentes emisores. |
Campos de encabezado de uso común | Los siguientes campos se utilizan comúnmente en el encabezado de un JWT | |
typ | Tipo de token | Si está presente, debe configurarse en un tipo de medio IANA registrado. |
cty | Tipo de contenido | Si se utiliza firma anidada o encriptación, se recomienda configurar esto en JWT ; de lo contrario, omita este campo. [1] |
alg | Algoritmo del código de autenticación de mensajes | El emisor puede configurar libremente un algoritmo para verificar la firma en el token. Sin embargo, algunos algoritmos admitidos no son seguros. [10] |
kid | Identificación de clave | Una pista que indica qué clave utilizó el cliente para generar la firma del token. El servidor comparará este valor con una clave registrada para verificar que la firma sea válida y que el token sea auténtico. |
x5c | Cadena de certificados x.509 | Una cadena de certificados en formato RFC4945 correspondiente a la clave privada utilizada para generar la firma del token. El servidor utilizará esta información para verificar que la firma es válida y que el token es auténtico. |
x5u | URL de la cadena de certificados x.509 | Una URL donde el servidor puede recuperar una cadena de certificados correspondiente a la clave privada utilizada para generar la firma del token. El servidor recuperará y utilizará esta información para verificar que la firma sea auténtica. |
crit | Crítico | Una lista de encabezados que el servidor debe comprender para aceptar el token como válido |
Código | Nombre | Descripción |
Existen implementaciones de JWT para muchos lenguajes y marcos, incluidos, entre otros:
Los tokens web JSON pueden contener el estado de la sesión. Pero si los requisitos del proyecto permiten la invalidación de la sesión antes de la expiración del JWT, los servicios ya no pueden confiar en las afirmaciones del token solo por el token. Para validar que la sesión almacenada en el token no se revoque, las afirmaciones del token deben verificarse con un almacén de datos . Esto hace que los tokens ya no sean apátridas, lo que socava la ventaja principal de los JWT. [36]
El consultor de seguridad Tim McLean informó sobre vulnerabilidades en algunas bibliotecas JWT que usaban el alg
campo para validar tokens de manera incorrecta, generalmente al aceptar un alg=none
token. Si bien estas vulnerabilidades fueron corregidas, McLean sugirió descontinuar el alg
campo por completo para evitar una confusión de implementación similar. [10] Aún así, se siguen encontrando nuevas alg=none
vulnerabilidades en circulación, con cuatro CVE presentados en el período 2018-2021 que tienen esta causa. [37] [ se necesita una mejor fuente ]
Con un diseño adecuado, los desarrolladores pueden abordar las vulnerabilidades de los algoritmos tomando precauciones: [38] [39]
alg
campo)En 2017 se descubrió que varias bibliotecas JWT eran vulnerables a un ataque de curva elíptica no válida. [40]
Algunos han argumentado que los tokens web JSON son difíciles de usar de forma segura debido a los muchos algoritmos y opciones de cifrado diferentes disponibles en el estándar, y que se deberían usar estándares alternativos tanto para los frontends web [41] como para los backends. [42]