JSON Web Token

JSON Web Token

 

Why use them?

Let us suppose we have to develop a web application that needs authentication and authorization. This creates the necessity to stablish a system that makes sure an entity is who he says he is and to determinate which accesses that entity has. This is the case of most web applications that are developed nowadays.

Let’s suppose now that many levels of accesses are required for various roles that a user may have.

This could be solved by using a traditional approach that includes creating a session on the server and then sending a cookie back to the client. First the session must be created and kept alive in the server. Besides, each request must be validated and for that to happen it could be necessary to access the database in order to corroborate that the user is authorized to do what he is requesting.

If you also wanted to implement a Single-Sign On, that would make things way more complicated.

JWT

JWT

JWT

A JSON Web Token (JWT) is a joint of claims (A “claim” is a piece of information about something, such as a user’s role), coded as a digitally signed JSON object. As such, this object has, an ensemble of key/value elements, where the keys are strings, and values are JSON objects. These elements represent the claims that are contained in the JWT.

These JWT are transmitted as a string that can be separated in three different parts.

The first one is the “JOSE Header” and states that this is a JWT object, as well as the algorithm used to sign it. It is a JSON object with this structure:

{

“typ”       :     “jwt”,

“algo”      :     “HS256”

}

In this example, the JOSE Header indicates that this is a JWT object and was encrypted using the “HMAC SHA256” algorithm.

In addition, this object is passed to the string to then be codified using Base64.
In this case, we obtain the following result:

eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9

The second part is an object that contains the claims that are intended to be transmited. These are represented by key/value elements. Some of the keys can be previously registered and have a specific meaning that should be the same for every entity that has the capacity to read a JWT. There are also keys that are specific to each application. An example of this group of claims may be:

{

“exp”       :     “1517454000000”,

“roles”     :     [

“rol1”,

“role3”,

“role7”

]

}

In this case the JWT has an expiration date (“exp” is one of the keys which meaning should be the same to all JWT’s) 1 January of 2018 has an element with key “roles” which value is an array for the roles of the user who ordered the JWT.

In addition, this object is converted to string and then be encoded using Base64.
In this case, we obtain the following result:

eyJleHAiOiIxNTE3NDU0MDAwMDAwIiwicm9sZXMiOlsicm9sZTEiLCJyb2xlMyIsInJvbGU3Il19

Finally, the JWT signature is obtained; this is accomplished by linking the two strings generated in the previous step with a dot in the middle.

eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9. eyJleHAiOiIxNTE3NDU0MDAwMDAwIiwicm9sZXMiOlsicm9sZTEiLCJyb2xlMyIsInJvbGU3Il19

Then by using a cryptographic algorithm this value gets signed. There are many of these algorithms; the most popular ones are HS256 (that uses a unique and private password) and RS256 (that uses a public/private key-pair that verifies/generates the signature). In this case, since the JWT used as an example has a JOSE Header using HS256, a private key that must be secret will be used (this key is never sent to the client). In this case, it will be Passw0rd.

Therefore the signature will be:

hDdvBmDHDVg1OPjE0CJKv6h9HsxCpQOcq_LvQJyf5pA

In the jwt website there is an excellent tool that helps to verify if the JWT obtained or generated are correctly signed or if there is any error.

At the end, all of the values together generate the JWT, which in this case would be:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNTE3NDU0MDAwMDAwIiwicm9sZXMiOls icm9sZTEiLCJyb2xlMyIsInJvbGU3Il19.hDdvBmDHDVg1OPjE0CJKv6h9HsxCpQOcq_LvQJyf5pA

 

Functioning

The user logs into the system with his credentials as usual (trying not to call this process “Signing in”). Then the server sends the client a JWT that should be saved locally.

At this point, there are two important things to highlight. The first is that the server no longer keeps the users’ information. Since the load to the server is reduced, the responsibility to maintain their identity is now transferred to the clients

It also allows the use of services that have parameters entirely defined by the information that the client sends, since it is signed, it is possible to know if the content has been modified, and if it is, to act according to the situation; generally denying the access to the service. The usual way to invoke a service using JWT is by adding an Authorization HTTP Header.
Using our example:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNTE3NDU0MDAw MDAwIiwicm9sZXMiOlsicm9sZTEiLCJyb2xlMyIsInJvbGU3Il19.hDdvBmDHDVg1OPjE0CJKv6h9 HsxCpQOcq_LvQJyf5pA

Secondly, the client gets access to all of the claims of the JWT. Which means that is no longer necessary to access the server in order to obtain this information each time it is required, since it is available from the beginning.

Advantages

As mentioned before one of the main advantages is the fact that you reduce the server load. Not only by having to maintain the session but also by querying the database in some cases. As well as the possibility of using services, that do not depend on a previous status.

If we compare JWT to other token standards such as SAML (a very popular one in the industry, mostly used in enterprise applications), it is possible to observe that JWT is way more compact, and that makes it more useful in environments where efficiency on the use of web resources is needed, such as, websites and mobile applications.

In addition, JSON has a much extended use, so almost any language has tools to convert from and for this format to objects and vice versa, unlike XML.

As a last appreciation, I would like to highlight the fact that it allows to design enterprise architectures with the possibility of having Single-Sign On under the same domain in a relatively simple way. This happens because it is possible to use the JWT obtained from an application into the others without any trouble, since the localStorage is kept under the same domain, assuming that all the applications, somehow, can verify if the JWT is valid or not.

 

 

—————————————————————————————————————————————–

 

 

JSON Web Token

Motivación

Supongamos que tenemos que desarrollar una aplicación web que necesite autenticación y autorización. Esto es establecer que una entidad es quien dice ser, y además, determinar a qué tiene acceso esta entidad. Este es el caso de la mayoría de las aplicaciones web que se desarrollan. Supongamos que se requieren diversos niveles de acceso para varios roles que pudiese tener un usuario.

Una solución utilizando el enfoque tradicional incluiría crear una sesión en el servidor y devolverle una cookie al cliente. Esto implica, primero que nada, mantener la sesión viva en el servidor. Además, en cada pedido, se debe realizar la validación de que lo que se quiere, por lo que puede ser necesario acceder a la base de datos para corroborar que el usuario tiene permitido el acceso.

Si además fuese deseable implementar Single-Sign On la tarea se volvería bastante más complicada.

JWT

JWT

Un JSON Web Token (JWT) es un conjunto de claims (Un “claim” es información acerca de algo, por ejemplo el rol de un usuario), codificado como un objeto JSON firmado digitalmente. Como tal, este objeto consta de un conjunto de elementos clave/valor, donde las claves son strings y los valores objetos JSON. Estos elementos representan los claims contenidos en el JWT.

Estos JWT se trasmiten como un string que se puede separar en tres partes.

La primera se conoce como JOSE Header y declara que el objeto es un JWT, así como también el algoritmo utilizado para firmarlo. Es un objeto JSON con la siguiente estructura:

{

“typ”       :     “jwt”,

“algo”      :     “HS256”

}

En este caso, de ejemplo, el JOSE Header indica que el objeto es un JWT y además fue encriptado utilizando el algoritmo “HMAC SHA256”.

A su vez, este objeto se pasa a string y luego se codifica utilizando Base64.
El resultado en este caso es:

eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9

 

La segunda, es un objeto que contiene los claims que se quieren transmitir. Estos son representados por elementos clave/valor. Algunas de estas claves se encuentran previamente registradas y tienen un significado específico que debería ser común a toda entidad capaz de leer un JWT. A su vez, se tienen claves que son propias de cada aplicación. Un ejemplo de este conjunto de claims es:

{

“exp”       :     “1517454000000”,

“roles”     :     [

“rol1”,

“role3”,

“role7”

]

}

En este caso, de ejemplo, el JWT tiene una fecha de expiración (“exp” es una de las claves cuyo significado debe ser común a todos los JWT) 1 de Enero de 2018 y tiene un elemento con clave “roles” y cuyo valor es un array con los roles del usuario que pidió el JWT.

A su vez, este objeto se pasa a string y luego se codifica utilizando Base64.
El resultado en este caso es:

eyJleHAiOiIxNTE3NDU0MDAwMDAwIiwicm9sZXMiOlsicm9sZTEiLCJyb2xlMyIsInJvbGU3Il19

 

Por último, se obtiene la firma del JWT. Esta se logra concatenando los dos strings obtenidos en el paso anterior con un punto en el medio.

eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9. eyJleHAiOiIxNTE3NDU0MDAwMDAwIiwicm9sZXMiOlsicm9sZTEiLCJyb2xlMyIsInJvbGU3Il19

Luego, utilizando un algoritmo criptográfico se firma este valor. Hay muchos algoritmos de este tipo, aunque los más utilizados son HS256 (que utiliza una única clave privada) y RS256 (que utiliza un par de claves pública/privada con la que se verifica/genera la firma respectivamente). Para este ejemplo, como el JWT se definió en su JOSE Header utilizando HS256, se utilizará una clave privada que debe ser secreta (es decir que nunca viaja al cliente). Para nuestro caso esta será: Passw0rd.

Por lo tanto la firma será:

hDdvBmDHDVg1OPjE0CJKv6h9HsxCpQOcq_LvQJyf5pA

En la página jwt existe una excelente herramienta que permite verificar si los JWT obtenidos o generados se encuentran correctamente firmados o si tienen algún error.

 

Por último, se concatenan todos los valores y se obtiene el JWT. Para nuestro ejemplo será:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNTE3NDU0MDAwMDAwIiwicm9sZXMiOls icm9sZTEiLCJyb2xlMyIsInJvbGU3Il19.hDdvBmDHDVg1OPjE0CJKv6h9HsxCpQOcq_LvQJyf5pA

 

Funcionamiento

Al igual que normalmente, el usuario ingresa al sistema con sus credenciales (intentando no llamar a este procedimiento “Inicio de Sesión”). El servidor devuelve al cliente un JWT que deberá ser guardado localmente.

En este punto, hay dos cosas importantes que resaltar. La primera es que el servidor ya no mantiene constantemente la información del usuario. Es decir, se reduce la carga en el servidor, y la responsabilidad de mantener la identidad pasa a ser del cliente. A su vez, permite la utilización de servicios cuyos parámetros son definidos enteramente por la información que envía el cliente, ya que al estar firmado es seguro si el contenido del mismo fue modificado es posible saberlo y actuar apropiadamente, generalmente no permitiendo el acceso al servicio. Por lo general, la forma de invocar un servicio utilizando JWT es agregando un Header HTTP llamado Authorization, utilizando nuestro ejemplo:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNTE3NDU0MDAw MDAwIiwicm9sZXMiOlsicm9sZTEiLCJyb2xlMyIsInJvbGU3Il19.hDdvBmDHDVg1OPjE0CJKv6h9 HsxCpQOcq_LvQJyf5pA

Una segunda consecuencia, es que el cliente tiene acceso a todos los claims del JWT. Esto significa que no es necesario acceder al servidor para obtener esta información cada vez que se requiere ya que se encuentra disponible desde el primer momento.

 

Ventajas

Como se dijo antes, una de las ventajas es que se le quita carga al servidor. No sólo en tener que mantener la sesión sino también en la realización de consultas a la base de datos en algunos casos. Así como también la posibilidad de utilización de servicios que no dependan de un estado previo.

Si comparamos JWT con otros estándares de token por ejemplo SAML (bastante utilizado en la industria, más que nada para aplicaciones empresariales), se puede ver que JWT es mucho más compacto, por lo que es mucho más útil en entornos donde se requiere eficiencia en el uso de los recursos de red, como por ejemplo páginas web y aplicaciones móviles.

A su vez, el uso de JSON se encuentra sumamente extendido, por lo que casi cualquier lenguaje posee herramientas para convertir desde este formato a objetos y viceversa; a diferencia de XML.

Como última apreciación, es que permite el diseño de arquitecturas empresariales con la posibilidad de Single-Sign On bajo el mismo dominio de manera relativamente sencilla, debido a que se puede utilizar el JWT obtenido de una aplicación en las otras sin problemas, ya que el localStorage (que es en el browser el lugar donde se guarda generalmente) se mantiene bajo el mismo dominio, suponiendo que todas las aplicaciones, de alguna manera, pueden verificar si el JWT es válido o no. A su vez permite la simplificación de estas arquitecturas en caso de operar bajo diferentes dominios.

 

Share This
Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn