Consumidores, Autenticación, y Autorización de APIs en Kong – I

Kong Gateway permite la configuración de diferentes mecanismos de autenticación (ej: Basic Auth, Key Auth, etc.), así como permite definir Consumidores, a los que podemos asociarles credenciales y añadirles a grupos para darles acceso a nuestras APIs, mediante la configuración de ACLs que permitan el acceso a nuestras APIs sólo y exclusivamente a los usuarios permitidos. En este Post vamos a ver como configurar paso a paso tanto Basic Auth como Key Auth, mediante un ejemplo práctico, utilizando uno o ambos mecanismos de autenticación simultáneamente.

Continuando con la serie de Posts acerca de Kong, después de haber hecho una breve introducción a Kong, Konga, y a la publicación de Servicios (APIs), en este nuevo Post vamos a tratar el tema de la Autenticación de APIs en Kong con foco en la autenticación básica y de API Key, que es uno de los puntos más importantes al utilizar un API Manager, ya que no sólo evitamos implementar esa lógica en nuestras APIs (minimizando el esfuerzo de desarrollo), sino que además lo tenemos todo junto y centralizado en un único sitio, y eso mola mucho.

Además del caso de uso de construir APIs para ser utilizadas como Backend de una aplicación, también tenemos el caso de uso de la compañía o departamento que necesita compartir sus datos (APIs) con sus Clientes, Proveedores, Empleados, y cualquier otro tipo de tercero que pueda tener interés en consumir sus datos. Aquí la gestión de consumidores, autenticación y autorización que proporcionan los API Managers como Kong, es fundamental.

Para este fin, Kong permite la creación y configuración de Consumidores, a los que vamos a asociar unas credenciales e incluirlos en Grupos de Consumidores. De este modo van a poder identificarse y acceder a nuestros servicios (APIs).

La configuración de la Autenticación y Autorización de APIs en Kong la vamos a realizar mediante el uso de Plugins, que podremos activar en diferentes scopes en función de nuestras necesidades, por ejemplo, a nivel global, o de un servicio o ruta en particular. Principalmente vamos a necesitar Plugins de Autenticación (ej: Basic Auth, Key Auth, etc) así como el Plugin de ACL (para la Autorización). Podemos ver los Plugins disponibles en la documentación de Kong: Kong Hub - Plugins and Integrations

Como siempre, esta configuración la podemos realizar mediante llamadas a la API Admin de Kong (modelo imperativo), que es muy sencillo, aunque en nuestro caso nos vamos a apoyar en Konga como Dashboard y herramienta de administración.

Si quieres seguir este Post paso a paso, te recomiendo que te apoyes en el Docker Compose que compartí en GitHub (GitHub – ElWillieES – kong-docker-lab), y que sigas el anterior Post (Introducción a Kong Gateway y Kong Dashboard) en el que configuramos la publicación de varios Servicios (APIs) en Kong, y que utilizaré como base para los ejemplos que voy a realizar en este nuevo Post.

Configuración de Autenticación Básica en Kong (Basic Auth)

Lo primero que vamos a hacer es habilitar la Autenticación Básica en Kong, como medio de autenticación para todas nuestras APIs, por lo tanto, necesitamos habilitar el Plugin de Basic Auth a nivel Global. Para más información acerca del Plugin de Basic Auth: Kong – Plugin – Basic Auth

Vamos a hacerlo a través de Konga. Para ello, en la sección de Plugins, click en Add global plugins.

Podemos elegir entre varios Plugins de Autenticación, en nuestro caso nos interesa el de Basic Auth. Click en Add plugin para continuar.

En la siguiente pantalla hay alguna opción adicional que podríamos configurar, pero para nuestro laboratorio no necesitamos hacer nada más, tan sólo click en Add plugin, y listo.

Si ahora volvemos a comprobar los Plugins que tenemos instalados, podremos vere cómo ya aparece el Plugn de Basic Auth, con scope global.

Si ahora intentamos acceder a cualquiera de nuestras APIs a través de Kong con un navegador, veremos que nos pide credenciales (autenticación básica).

Si intentamos acceder con Postman, ocurre lo mismo, y nos encontraremos con un 401 como una catedral.

Mismo intento con un curl (y mismo resultado, claro).

Hasta ahora, la verdad que ha sido super fácil, añadir el Plugin de Basic Auth a nivel global, y listo. Pero claro, ¿con qué credenciales debemos acceder a nuestros servicios (APIs)? ¿Cómo podemos controlar quién puede acceder a qué servicio (API)? No es mucho más complicado. Vamos a verlo.

Configuración de Consumidores, Grupos de Consumidores, y ACLs

Kong permite hacer una gestión de los Consumidores, a los que podemos asociar credenciales, pudiendo crear Grupos de Consumidores a los que dar permisos de acceso (ACLs) mediante el uso del Plugin de ACLs, como vamos a ver en el siguiente ejemplo. Para más información acerca del Plugin de ACL: Kong – Plugin – ACL

Un Consumidor no tiene necesariamente que ser un Usuario (habitualmente agrupa varios usuarios), es decir, por ejemplo, un Consumidor podría ser una empresa (ej: un Cliente o un Proveedor) en la que creamos varias credenciales, para los diferentes usuarios y aplicaciones que consumen nuestras APIs desde dicha compañía. De hecho, veremos que podremos crear múltiples credenciales de tipo Basic Auth para un mismo Consumidor, cada una formada por una pareja usuario/contraseña.

Podemos crear un Consumidor utilizando Konga, desde la sección Consumers, haciendo click en Create consumer. Principalmente deberemos asignar un nombre al consumidor, y click en Submit consumer. Ojo, no confundir con la sección Users (esta última es para crear usuarios en Konga, para el acceso al propio Dashboard… el acceso a nuestras APIs es a través de Consumers).

Una vez creado el Consumidor, desde la pestaña Credentials, le podemos asignar credenciales. En nuestro caso queremos que sean de tipo Basic. Click en Create credentials.

Especificaremos las credenciales que deseamos que utilice el consumidor (username y password), y click Submit.

Sólo con esto, ya tenemos disponible un Consumidor con una credenciales de tipo Basic Auth, por lo que si probamos ahora el acceso a cualquiera de los Servicios que estamos publicando a través de Kong, especificando estas credenciales, podremos acceder con éxito a dicho servicio (en lugar de obtener un 401, como nos pasaba antes).

Del mismo modo, si probamos desde Postman, especificando las credencias de tipo Basic Auth, ahora si que podremos acceder con éxito obteniendo un 200.

Esto está bien, y puede ser que en muchas ocasiones sea suficiente sólo con esta configuración. Sin embargo, tiene el inconveniente de que el consumidor puede acceder a todas nuestras APIs.

¿Qué podemos hacer si queremos que un Consumidor pueda acceder a unas APIs, pero que no tenga acceso a otras? La solución es muy sencilla: Podemos crear Grupos de Consumidores y configurar ACLs sobre las Rutas o Servicios de nuestras APIs, para así pode restringir el acceso. Vamos a verlo con un ejemplo.

Por un lado, en la pestaña Groups de nuestro consumidor, haremos click en Add a group, y le añadiremos al grupo service-a-consumers (al añadirlo a un grupo, si el grupo no existe, se crea automáticamente). Si tuviéramos más consumidores que quisiéramos añadir a este mismo grupo, lo repetiríamos con cada uno de ellos.

Para poder probarlo bien, vamos a crear otro consumidor (peter), con credenciales de tipo Basic Auth, pero no le vamos a añadir a ningún grupo de consumidores, mientras que el primer consumidor (willie) es miembro del grupo service-a-consumers.

Lo siguiente que vamos a hacer es añadir un Plugin sobre sobre la ruta service-a. Para ello, en la sección Routes, editaremos la ruta service-a, y en la pestaña de Plugins, click en Add plugin.

Seleccionaremos el Plugin ACL de tipo Security, y click en Add Plugin.

Al añadir el Plugin ACL, tenemos la posibilidad de especificar directamente a qué Grupos de Consumidores permitir o denegar acceso. En nuestro caso, permitiremos el acceso al grupo service-a-consumers, y click en Add Plugin.

Hecho esto, hemos conseguido nuestro propósito:

  • El Servicio A está protegido con ACLs (sólo pueden acceder los consumidores autenticados que estén permitidos en las ACL), mientras que el resto de servicios (B y C) tan sólo requieren que acceda un consumidor autenticado (puede acceder cualquiera).
  • Al acceder al Servicio A con un usuario (ej: willie) miembro de un grupo (ej: service-a-consumers) permitido, se consigue acceder con éxito, como lo vemos en navegador verde.
  • Al acceder al Servcio A con un usuario (ej: peter) que no es miembro de ningún grupo permitido, no se consigue acceder con éxito a dicho servicio, aunque si es posible acceder con éxito a otros servicios que no tienen ACLs, como lo vemos en el navegador negro (ventanas de incógnito).

A continuación podemos ver el acceso con éxito al servicio utilizando un curl con autenticación básica.

Como hemos podido ver, ha sido bastante sencillo de configurar, y lo hemos podido hacer utilizando Konga, sin ningún problema.

Configuración de Autenticación por clave en Kong (Key Auth)

Ahora vamos a probar la autenticación por clave (Key Auth) utilizando el Plugin correspondiente. Para más información acerca del Plugin de Key Auth: Kong – Plugin – Key Auth

En este ocasión queremos mantener ambas, la autenticación básica (Basic Auth) y la de clave (Key Auth), de tal modo que puedan convivir ambos métodos de autenticación, pueda haber usuarios que utilicen Basic Auth, otros usen API Key, e incluso otros que puedan utilizar indistintamente Basic Auth ó API Key. Esto requiere alguna configuración especial, como se describe en la documentación de Kong: Kong Gateway - Allowing Multiple Authentication Methods

El principal truco para poder configurarlo, es que vamos a necesitar crear un consumidor anónimo (anonymous) sin ninguna credencial asociada, que utilizaremos como fallback en los Plugins de autenticación, y que no tendrá permisos para nada.

Es importante que apuntemos el ID del consumidor anónimo, que desde Konga lo podemos ver en la URL al ver los detalles del consumidor (en nuestro caso de ejemplo es: 25d901e2-f3db-4614-82b7-95be47970018).

También es necesario añadir el Plugin Request Termination con scope global, especificando el ID del consumidor anónimo (anonymous) que acabamos de crear, así como el resto de detalles que vemos a continuación.

Además, necesitamos configurar en el Plugin de Basic Auth el ID del usuario anónimo que acabamos de crear, para que haga fallback.

Todos estos pasos, sólo son necesarios porque deseamos utilizar múltiples Plugins de autenticación, si sólo quisiéramos utilizar uno (sea Basic Auth ó Key Auth) no sería necesario. En cualquier caso, no es tan complicado, tan sólo hay que tenerlo en cuenta.

Hecho esto, contiamos. Ahora vamos a configurar el Plugin de Key Auth sobre la ruta del Servicio A, de tal modo, que sólo estará disponible para dicho Servicio.

Para añadir el Plugin, en la sección de Routes, entramos a la ruta service-a, y en la pestaña de Plugins, click en Add Plugin. Podremos observar que tenemos el Plugin ACL que configuramos antes, y a diferencia de la otra ocasión, esta vez vamos a añadir un Plugin de Autenticación a nivel de una ruta, en lugar de a nivel global (como hicimos antes con el Plugin de Basic Auth).

Seleccionaremos el Plugin de Key Auth y click en Add Plugin.

En la siguiente pantalla, hay varias opciones adicionales que podemos configurar del Plugin Key Auth. En nuestro caso vamos a configurar el ID del usuario anónimo que acabamos de crear (para que haga fallback), la propiedad key name (especificaremos los nombres de los encabezados que utilizaremos para enviar la Key, en nuestro caso podríamos utilizar apikey ó api-key) y deshabilitaremos la opción que permite enviar ka Key en la URL (por seguridad, es preferible que la Key sólo se envíe en el encabezado). Hecho esto, click en Add plugin para continuar.

Lo siguiente que tenemos que hacer es configurar en un consumidor una credencial de tipo API Key. En nuestro caso de ejemplo, lo vamos a realizar sobre los dos consumidores que hemos creado, uno pertenece a un grupo con acceso al Servicio/Ruta que vamos a probar (service-a), mientras que el otro no tiene acceso, debido a como configuramos antes los grupos y ACLs. Para crear una credencial de tipo API Key, editamos un Consumidor, y en la página de Credentials, seleccionamos la pestaña API Keys, y click en Create API Key.

En el siguiente diálogo, podemos especificar nosotros el valor que deseamos para la Key, o bien, dejarlo en blanco y permitir que Kong genere una Key de forma aleatoria. Click en Submit para continuar.

Con esto ya tenemos una API Key asociada a un Consumidor. Repetiremos este mismo proceso en el otro consumidor, para que ambos tengan credenciales de tipo API Key, y así poder hacer pruebas.

Con esto, ya estaría todo configurado. Vamos a probarlo.

El consumidor willie, tiene credenciales de tipo Basic y Key, y es miembro de un grupo que le da acceso al Servicio A (está permitido en las ACLs), por lo tanto, puede acceder al Servicio A utilizando Basic Auth o Key Auth. Al intentar acceder al Servicio C (este sólo permite Basic Auth y no tiene ACLs), mediante API Key obtiene un 401 pero con Basic Auth puede acceder con éxito, ya que no hay ACLs y el Plugin Basic Auth es global.

Sin embargo, el consumidor peter, tiene credenciales de tipo Basic y Key, pero no es miembro de ningún grupo que le da acceso al Servicio A en las ACLs, por lo tanto, no puede acceder al Servicio A ni con Basic Auth ni con Key Auth, obteniendo siempre un 403 Forbidden. Al intentar acceder al Servicio C (este sólo permite Basic Auth y no tiene ACLs), mediante API Key obtiene un 401 pero con Basic Auth puede acceder con éxito, ya que no hay ACLs y el Plugin Basic Auth es global.

Despedida y Cierre

Hasta aquí llega este Post sobre Kong y Konga, donde hemos realizado una introducción al consumo de APIs en Kong, explicando el funcionamiento y configuración de Consumidores, Grupos, autenticación básica (Basic Auth) y por clave (Key Auth), configuración de ACLs (Autorización), y configuración de múltiples mecanismos de auténticación (en particular con Basic Auth y Key Auth), continuando con el ejemplo que vimos en el anterior Post Introducción a Kong Gateway y Konga Dashboard, y utilizando el Docker Compose compartido en GitHub para quienes deseen seguir este laboratorio paso a paso: GitHub – ElWillieES – kong-docker-lab

Los métodos de autenticación básica y por clave, aunque no son muy seguros (la petición incluye las credenciales), siguen siendo bastante utilizados.

Poco más por hoy, como siempre confío que la lectura resulte de interés.