JWT Validation

El JSON Web Token (JWT) es un estándar abierto (RFC 7519) que define una forma compacta y autosuficiente para la transmisión segura de información entre dos partes como un objeto JSON. La información se puede verificar y confiar porque hay firma digital.

Los JWT se pueden firmar usando un secreto (con el algoritmo HMAC) o un par de claves pública y privada usando RSA.

Para leer más sobre esto, vaya a https://jwt.io/.

Generar un token

Antes de realizar la llamada para generar el token JWT, debemos realizar una llamada para generar el Authorization Code. Puedes ver más sobre esto aquí.

Para usar el interceptor JWT, se debe crear una aplicación, por lo que tenemos acceso al client ID y client secret.

Para generar el JWT, debe realizar una operación POST para el endpoint <url>/oauth/access-token del gateway.

El header debe contener la siguiente información:

Authorization : Basic client_id:client_secret
Este client_id:client_secret debe ser tipo string convertido a Base64, utilizando los datos de la aplicación creada.

A continuación se muestra un ejemplo de header con client ID y secret convertidos a Base64:

Authorization : Basic ZjkyMTIxNzMtZTcwNS0zNzNiLWE2OTgtNjE5MjNlMzc4MzU5OjAyYWI1Mjg4LTkyZGItM2FiMy05OWZkLWZhYzRhZjg1N2Q4MQ==

En el cuerpo, debemos pasar el código generado por el endpoint de grant-code con algunos elementos más, en el formato x-www-form-urlencoded:

"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer"
"code" : "8748d39f-1d4f-311f-92c6-4b279db1b317"

Además de generar un JWT, también es posible crear un token cifrado utilizando el estándar JWE (JSON Web Encryption). Para saber cómo generar un JWE y proteger el contenido del token con cifrado, consulte el tema JWE (JSON Web Encryption).

Por último, su token de acceso será generado de nuevo y debe aparecer como se muestra a continuación:

{
  "access_token": "ca81cb16-43e4-3e96-aaea-4861e7791dc7",
  "refresh_token": "677b881a-d0b6-3b29-b9a8-f0cdb50ce035",
  "token_type": "access_token",
  "expires_in": 3600
}
Si su API retorna el status code 401 Unauthorized al utilizar este interceptor, es posible que el token no sea válido. Consulte más detalles en esta página de nuestras preguntas frecuentes.

Flujo

Este interceptor solo se puede introducir en el flujo de peticiones (request) y contiene dos datos obligatorios: ubicación (location) y nombre (name).

Las opciones de ubicación son:

  • Query Param: valida la existencia de un JWT pasado a través de query param.

    • La propiedad "Name" define el nombre de query param esperado.
      jwt queryparam

  • Header: valida un JWT pasado en un header.

    • La propiedad "Name" define el nombre de header esperado.
      jwt header

  • Default JWT Header: valida un JWT pasado en un header.

    • Para esta opción, no hay ninguna propiedad "Name"; en este caso, el JWT se espera en el header Authorization.
      jwt defaultHeader

JWE

Como mencionamos al principio de esta página, JWT es un estándar que permite la transmisión de tokens de una parte a otra con seguridad con respecto a la legitimidad del token pasado. Es bastante común usar este patrón para enviar otras informaciones adicionales, a través de claims.

Sin embargo, es importante tener en cuenta un aspecto de JWT: es un estándar que garantiza la fiabilidad de los datos, pero no su confidencialidad. La información confidencial que se pasa en el cuerpo del token se puede interceptar y exponer.

El JWE (JSON Web Encryption) añade una capa adicional de seguridad al token al cifrar los datos transmitidos. De esta forma, es posible ampliar la funcionalidad del JWT para que, además de garantizar la autenticidad e integridad, también asegure la confidencialidad de la información transmitida.

Opción Use JWE-JSON Web Encryption

Cuando la opción Use JWE-JSON Web Encryption está activada, el token cifrado en la solicitud es validado, descifrado y luego enviado al backend. Este proceso garantiza que solo los sistemas autorizados puedan acceder al contenido del token, reforzando la seguridad de extremo a extremo en la comunicación entre las partes.

jwt jwe

Requisitos para la ejecución del flujo

Para realizar el flujo correctamente, es necesario:

  • Tener una API con interceptores OAuth, configurada para JWT y JWT Validation interceptor, con la funcionalidad JWE-JSON Web Encryption activada.

  • Tener una App asociada a la API.

  • Tener un Plan relacionado con la API.

Asegúrate de que la API OAuth 2.0 esté disponible en tu entorno. De lo contrario, será necesario crearla antes de continuar.

Los siguientes pasos dependen de los requisitos anteriores. Asegúrate de que todos estén completados antes de continuar.

Generando el JWE

El proceso de generación del JWE implica dos etapas principales:

1. Generar grant code

La generación de un grant code es una etapa esencial para crear el JWE.

Realiza una solicitud POST a la ruta /oauth/grant-code de la API OAuth, como se muestra en el siguiente ejemplo:

Request
curl --location '<gateway_url>/oauth/grant-code' \
--header 'Content-Type: application/json' \
--data '{
  "client_id": "<app_client_id>",
  "extraInfo": {},
  "redirect_uri": "http://localhost/",
  "state": "string"
}'

Reemplaza:

  • <app_client_id> por el valor del client_id de tu App.

  • <redirect_url> por la URL de redirección deseada.

  • <gateway_url> por la dirección del gateway de tu entorno.

Response
{
  "redirect_uri": "http://localhost/?state=string&code=**40a7848a-2615-49ba-ae27-cff175095c16**"
}

Después de realizar la solicitud, se devolverá una respuesta con el "redirect_uri".

Copia el valor de "code" devuelto, ya que se usará en el siguiente paso.

La API debe contener un interceptor OAuth con la opción JWT marcada. De lo contrario, ocurrirá un bad request con un mensaje indicando que el grant type es inválido.

Ejemplo de respuesta
{
    "result": "failure",
    "errors": [
        {
            "type": "INVALID",
            "message": "grand_type!"
        }
    ],
    "status": 400
}

2. Generar JWE

Con el code obtenido, es momento de generar el JWE. Consulta el siguiente ejemplo de solicitud:

Request
curl --location 'https://<gateway_url>/oauth/access-token' \
--header 'Authorization: Basic NmM5MWUwNDQtYTJkMS00ZmFiLTkwYjgtMWRhNmMwZDc2YWMzOjI5Y2I4ODE1LWM2ODEtNGIwZC04Yzc2LTg2NzdmMzFlODY2Yg==' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
--data-urlencode 'code=40a7848a-2615-49ba-ae27-cff175095c16' \
--data-urlencode 'encrypt=true'

El parámetro encrypt=true es obligatorio para que el token se genere en el formato JWE (JSON Web Encryption). Sin este parámetro, el token se emitirá como un JWT sin cifrado, lo que expone la información en el payload.

En el ejemplo anterior:

  • El parámetro code debe contener el valor obtenido en la etapa anterior.

  • El parámetro encrypt=true indica que el token se transmite con JWE – JSON Web Encryption habilitado.

Adapta el ejemplo según sea necesario:

  • Incluye el header Authorization con el código Base64 de tu App;

  • Inserta el code obtenido anteriormente;

  • Agrega el parámetro encrypt=true;

  • Sustituye <gateway_url> por la dirección del gateway de tu entorno.

La solicitud debe enviarse en el formato x-www-form-urlencoded.

Response
{
  "access_token": "eyJleHAiOjE3NTUyODAxMzIyNDEsImFsZyI6ImRpciIsImVuYyI6IkExMjhHQ00ifQ..6r0yEMyxMrCutmGq.ywwIieYyG79S5G1ZEk1V9HDrYyvNknP_G1u4Wpzw3yW3-FAJT-oHuQUIRGVpqXtphOyEKaw-WNUhZYsasnX6o_Ju8uRLjEPVdeVa8y4SXU1c8wBWXe1jD9GK-TogVPAaaHrHq4q-iUL-gZJiOzsoCm0li3LgwjZPUq8A7RIcWUDSfsSZobow5Hi8xpn16L6V4iCcUZ-UA6hywS_UeR2J7uUPzj8273w8kAXvyWkWqrFnDf7Dv6T7vAY69vI3ZfBUgUquDD38V7gsmGuG6vSdcSRqKCYTvVgGCxbwPARJFxLw3rXE76R1F6GVmzmrSJQCtrcajNH5X_ZJnI9c12mnBGWwKtj8UjsJlsVBn4EAzWtxX6Fl-kXubclS1RW_VtcKXBd_yzBRCKUksR8QoHET2wDKSPJl9hg0-6g9xhvrSo-aVVo4FZkBQoBmAv7FN3C0CNwWJ5nId2mTnwckdAmHWqLpqq3rwcED42pLvy3pnYz4LHU5FZHQrk1Z0kExaVY_YOYJvN6fV-Whc5fSyG82B0R2AQ36AzxQq1-Fcqy9Xw.Ah69e5r8RS1MBqaJgS61wQ",
  "token_type": "access_token",
  "expires_in": null
}

Copia el valor del campo access_token. Este es tu JWE.

El uso de JWE sigue el mismo patrón que JWT. Para más detalles, consulte el tema JWT (JSON Web Token).

Validando el flujo JWE (opcional)

Para validar que el token fue realmente cifrado, puedes utilizar el JWT Debugger.

Podrás observar que el contenido del token no puede leerse, confirmando la aplicación del cifrado.

Para validar el funcionamiento de la opción Use JWE-JSON Web Encryption:

  1. Realiza una solicitud a tu API, proporcionando el client_id de tu App y el access_token (JWE) generado.

  2. En el campo destination de la API, utiliza un mock que permita visualizar la recepción del access_token ya descifrado — como Supermock Sensedia, por ejemplo.

Ejemplo de solicitud
curl --location 'https://api-sensediaqa1.sensedia-eng.com/jwt' \
--header 'client_id: 6c91e044-a2d1-4fab-90b8-1da6c0d76ac3' \
--header 'access_token: eyJleHAiOjE3NTUyODAxMzIyNDEsImFsZyI6ImRpciIsImVuYyI6IkExMjhHQ00ifQ..6r0yEMyxMrCutmGq.ywwIieYyG79S5G1ZEk1V9HDrYyvNknP_G1u4Wpzw3yW3-FAJT-oHuQUIRGVpqXtphOyEKaw-WNUhZYsasnX6o_Ju8uRLjEPVdeVa8y4SXU1c8wBWXe1jD9GK-TogVPAaaHrHq4q-iUL-gZJiOzsoCm0li3LgwjZPUq8A7RIcWUDSfsSZobow5Hi8xpn16L6V4iCcUZ-UA6hywS_UeR2J7uUPzj8273w8kAXvyWkWqrFnDf7Dv6T7vAY69vI3ZfBUgUquDD38V7gsmGuG6vSdcSRqKCYTvVgGCxbwPARJFxLw3rXE76R1F6GVmzmrSJQCtrcajNH5X_ZJnI9c12mnBGWwKtj8UjsJlsVBn4EAzWtxX6Fl-kXubclS1RW_VtcKXBd_yzBRCKUksR8QoHET2wDKSPJl9hg0-6g9xhvrSo-aVVo4FZkBQoBmAv7FN3C0CNwWJ5nId2mTnwckdAmHWqLpqq3rwcED42pLvy3pnYz4LHU5FZHQrk1Z0kExaVY_YOYJvN6fV-Whc5fSyG82B0R2AQ36AzxQq1-Fcqy9Xw.Ah69e5r8RS1MBqaJgS61wQ'

Después de la ejecución, el backend recibirá el token ya descifrado, y será posible validar el flujo completo de la funcionalidad Use JWE-JSON Web Encryption.

Ejemplo de respuesta (parcial)
{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhcGktYXV0aG9yaXphdGlvbi5zaGFyZWQuc3ZjLmNsdXN0ZXIubG9jYWwiLCJpc3MiOiIxMC4xMzUuNTAuODUiLCJqdGkiOiI0N2UxM2Q3Mi05OGQ1LTRhOGQtODgzYi05NzFkMDgxYmQ0OTIiLCJzdWIiOiI2YzkxZTA0NC1hMmQxLTRmYWItOTBiOC0xZGE2YzBkNzZhYzMiLCJleHAiOjAsImlhdCI6MTc1NTI4MDEzMiwiQXBwOiAiOiJBcHAiLCJDb2RlOiAiOiI0MGE3ODQ4YS0yNjE1LTQ5YmEtYWUyNy1jZmYxNzUwOTVjMTYifQ.xJ7YfU_v0mb4ZTMmglPcj5g5zuJbDlFZnRoE-e8AplM",
    "token_type": "access_token",
    "expires_in": null
}
Thanks for your feedback!
EDIT

Share your suggestions with us!
Click here and then [+ Submit idea]