OAuth 2.0 con AWS, Kong y OAuth2 Proxy
A medida que las APIs se vuelven indispensables para nuestras aplicaciones, facilitar un acceso seguro a estos endpoints se vuelve más crítico que nunca. Uno de los protocolos más famosos para el acceso seguro es OAuth 2.0. Con OAuth 2.0 las aplicaciones pueden delegar de forma segura acceso a recursos sin exponer credenciales. Esto lo convierte en el estándar para autenticación y autorización en una gran variedad de plataformas, de aplicaciones móviles a aplicaciones web y otros como IoT.
A la hora de implementar OAuth 2.0, los API Gateways pueden ser utilizados como plataforma para este protocolo ya que al estar como punto de entrada de los requests se pueden llevar la tarea de autenticarlas y autorizarlas antes de que lleguen al backend. En este post veremos algunos ejemplos sobre cómo funciona OAuth 2.0 en tres API Gateways populares: AWS API Gateway, Kong y OAuth2 Proxy.
Descripción del escenario típico
Para nuestro ejemplo primero definimos cuatro actores:
- Usuario: es quien inicia el proceso para dar acceso a un tercero a una de sus cuentas, por ejemplo, para iniciar sesión en Spotify con su cuenta de Gmail.
- Spotify: es el servicio que desea obtener acceso a la cuenta del usuario, para nuestro ejemplo solo quiere obtener el nombre de usuario.
- Gmail Auth: el servicio que valida el usuario y emite los tokens. Este será el componente que implementaremos.
- Gmail: es el servicio de email el cual puede retornar el nombre de usuario.
La idea de este post es mostrar un flujo "Authorization Code" que lo podemos ver en el siguiente gráfico:
Kong
Kong es una solución de API Gateway basada en NGINX, para nuestro caso lo importante es entender que el Kong nos permite configurar URIs (llamadas rutas en Kong) apuntando a backends (llamados servicios).
Para nuestro ejemplo en Kong asumiremos que se cumplen estos puntos:
- Tenemos una API que retorna el nombre de usuario escuchando en el puerto 8000 del localhost, esta API no requiere autenticación alguna.
- Tenemos un Kong instalado y configurado con una base de datos, sin ningún servicio o ruta.
A grandes rasgos los pasos para configurar el Kong son:
- Crear un service apuntando a nuestra API.
- Crear una ruta apuntando al service, con esto se puede llamar al API a través del Kong y este queda como un simple proxy reverso.
- Agregar el plugin OAuth2 al service, con esto todas las llamadas al API fallaran ya que se requiere un access_token.
- Agregar un consumer al Kong.
- Crearle credenciales al consumer.
- Desplegar el proyecto kong-oauth2-hello-world para tener una web de autorización de prueba.
Con los pasos anteriores, el Kong queda configurado y listo para repetir bajo demanda los siguientes pasos:
- Nuestra aplicación nos redirecciona a una web externa donde se hará el login.
- Si el login es exitoso, el backend de esta web hace una llamada al Kong pidiendo un "auth code".
- La web recibe el "auth code" y redirige a la app a alguna uri importante.
- Intercambiar el "auth code" por un access_token.
- Llamar al endpoint de la API con el access_token.
OAuth2 Proxy
OAuth2 Proxy es una herramienta Open-Source que funciona como proxy entre los requests y el backend agregando protección con autenticación OAuth2 y OIDC. Puede ser utilizado de 2 formas: proxy y middleware, en el modo proxy, se encarga de interceptar y redirigir las peticiones al backend por sí mismo, mientras que en modo middleware, se integra a un proxy o balanceador de carga existente.
Al ser un proxy, este no posee un backend de seguridad por lo que solo se limita a autenticar a los usuarios contra uno de los OAuth providers compatibles, como Google, Keycloak, Azure, etc. por lo que el proceso de setup es el siguiente:
- Instalar el OAuth2 Proxy con un backend de prueba.
- Crear una aplicación OAuth en alguno de los proveedores, para pruebas recomendamos Digital Ocean por ser el más sencillo.
- Configurar el OAuth2 Proxy con los datos provistos por Digital Ocean que son Client ID y Client Secret de la aplicación.
- Probar acceder al backend, el OAuth Proxy se encargará de hacer la redirección al login de Digital Ocean para continuar.
AWS API Gateway
AWS API Gateway es una solución totalmente administrada que permite crear, desplegar y gestionar APIs de manera sencilla. Con su integración nativa con otros servicios de AWS (Cognito en nuestro caso) es posible crear arquitecturas seguras y sencillas de mantener.
A grandes rasgos la arquitectura es la misma que los 2 casos anteriores con las siguientes diferencias:
- API Gateway soporta prácticamente todos los proveedores OAuth del mercado, pero está mejor integrado a Cognito.
- Cognito puede tomar el rol de servidor de autenticación con su propia base de datos de usuario (user pool) o delegarlo a otro proveedor como Azure, siendo este paso extra transparente para el usuario final.
- Cognito cuenta con una página de login propia a diferencia de Kong.
El flujo de autorización y acceso es el siguiente:
- La aplicación se autentica directamente en Cognito, donde siguiendo el flujo se obtiene un access_token.
- Con el access_token se accede a un endpoint del API Gateway.
- Este endpoint llamado "Method" recibe la petición y el access_token.
- Este access_token se valida a través de un "Authorizer".
- El Authorizer hace una llamada a Cognito para verificar el token.
- Si es válido se reenvía la petición al backend real.