Autenticación con OAuth

OAuth

Un protocolo es una implementación estricta que evita confusiones y variaciones. Sin embargo, debido a la temprana adopción de OAuth, varias compañías han agregado sus propias versiones, lo que ha resultado en múltiples variantes de su implementación. En lugar de ser un protocolo estricto, OAuth se ha convertido en una guía de especificaciones/estandares. Esto plantea un desafío para implementar OAuth de manera segura y correcta, ya que la elección de la mejor forma depende de cada individuo. Para asegurar una buena implementación de OAuth, se recomienda no solo leer la especificación, sino también informarse sobre otras implementaciones y consejos de otras compañías.

Autenticación tradicional vs JWT

La autenticación tradicional se basa en la creación de un espacio en memoria que asigna un ID para identificar a los usuarios activos. Estos IDs se almacenan en cookies, que son eliminadas después de un tiempo límite, lo que significa que los usuarios deben volver a autenticarse para iniciar una nueva sesión.

Sin embargo, este enfoque de autenticación no es compatible con las aplicaciones de una sola página (Single Page Applications), ya que no se refresca el navegador para acceder a nueva información o para verificar la autenticación del usuario. Esto significa que no hay forma de acceder a las cookies a medida que los usuarios interactúan con la aplicación. También existen problemas cuando se construyen aplicaciones con arquitecturas basadas en microservicios, ya que cualquier control de permisos requiere hacer peticiones adicionales a la base de datos.

La autenticación con tokens, en cambio, genera tokens que contienen información de identificación y permisos de cada usuario. Estos tokens se envían y almacenan en el cliente, por lo que siempre que la aplicación necesite verificar los permisos de los usuarios, solo se necesita validar el token correspondiente. Gracias a este tipo de autenticación, no es necesario contar con un servicio de backend para almacenar las sesiones de autenticación de los usuarios. Solo se requiere guardar y validar los tokens para controlar los permisos de cada usuario.

Server-Side vs Client-Side sessions

La autenticación de usuarios en el lado del servidor se considera stateful, lo que significa que se utilizan sesiones para preservar el estado de autenticación. Para ello, se guarda en memoria o en una base de datos un identificador que permite comprobar si los usuarios están autenticados o no.

En cambio, la autenticación en el lado del cliente no utiliza sesiones. En este caso, no existe una forma de verificar si los usuarios están autenticados o no. En su lugar, se validan los datos de usuario para obtener tokens, que tienen un límite de tiempo y se utilizan en las solicitudes al servidor para validar el acceso y obtener información.

El proceso de autenticación en el lado del cliente es el siguiente:
  • Cuando los usuarios inician sesión, el servidor responde con un token que indica que el inicio de sesión fue exitoso. Desde el lado del cliente, se agrega una bandera que indica que el usuario está autenticado.
  • En cualquier momento de la aplicación (por ejemplo, cuando se cambia de ruta o se hace una nueva solicitud), se debe verificar si el token ha expirado.
  • Si el token ha expirado, se cambia la bandera para indicar que el usuario NO está autenticado y se redirecciona al usuario a la página de inicio de sesión.

OAuth 2.0

OAuth 2.0 nos permite refinar los estandares de OAuth con algoritmos mas concretos, el refinamiento se puede especificar usando el siguiente diagrama de flujo:


A más detalles estos estandares se especifican en las siguiente infografías:

Authorization Code Grant


Implicit Grant


Client Credentials Grant


Resource Owner Password Grant

La definición del Resource Owner Password Grant se encuentra en https://tools.ietf.org/html/rfc6749#section-4.3. Básicamente, este flujo de autenticación consta de los siguientes pasos:
  1. El usuario ingresa sus credenciales en el formulario de la aplicación cliente.
  2. La aplicación envía las credenciales al servidor de autorización.
  3. El servidor de autorización verifica las credenciales y emite un token de acceso.
  4. La aplicación utiliza el token de acceso para hacer llamadas a la API en nombre del usuario.

Authorization Code Grant (PKCE)

En la implementación de Authorization Code Grant en aplicaciones nativas, existe un riesgo de seguridad que permite que un atacante malintencionado intercepte el authorization_code devuelto por el Authorization Server y lo use para obtener un Access Token no autorizado.

Para evitar esto, se utiliza la técnica Proof Key for Code Exchange (PKCE), que se define en https://tools.ietf.org/html/rfc7636. En resumen, el algoritmo funciona de la siguiente manera:
  1. La aplicación nativa inicia el flujo de autorización y redirecciona al usuario al Authorization Server enviando los parámetros code_challenge y code_challenge_method.
  2. El Authorization Server redirecciona al usuario de vuelta a la aplicación nativa con un authorization_code en el query string.
  3. La aplicación nativa envía el authorization_code junto con el code_verifier, la URL de redireccionamiento (redirect_uri) y el client_id al Authorization Server para validar la información.
  4. El Authorization Server valida la información y devuelve un Access Token a la aplicación nativa.
  5. La aplicación nativa puede usar el Access Token para llamar recursos en nombre del usuario, como una API.
De esta forma, se reduce el riesgo de que un atacante malicioso pueda interceptar el authorization_code y obtener acceso no autorizado a los recursos protegidos.

¿Qué es OpenID Connect?

Si utilizamos OAuth 2.0 de forma incorrecta, podemos exponer a nuestros usuarios a diversos riesgos, por ejemplo, que alguien utilice el access_token para suplantar su identidad y obtener acceso no autorizado a su información.

Para solucionar esto, Open ID Connect se ha desarrollado como una capa de autenticación basada en OAuth 2.0. Es un estándar que nos permite utilizar los mecanismos adecuados para verificar la identidad de nuestros usuarios. Open ID Connect implementa los flujos de autenticación de Authorization Code Grant e Implicit Grant, pero con algunas mejoras. Además de obtener el access_token para hacer llamados a la API, Open ID Connect nos proporciona un nuevo token llamado id_token. Este token contiene información básica del usuario y nos permite verificar su autenticación de manera segura y confiable.

La diferencia entre OpenID (es la versión anterior a OpenID Connect) y OpenID Connect es que: Open ID da una manera de verificar la identidad del usuario, es decir, solo sirve como estandar de autenticación. Mientras Open ID Connect trabaja como extensión de OAuth 2.0 y además de solo servir como protocolo de autenticación, provee un JWT con detalles del usuario.

¿Qué es Auth0?

Auth0 es un servicio que ofrece soluciones completas para la gestión de autenticación y autorización en plataformas web y móviles. Su objetivo es permitir que desarrolladores y empresas puedan asegurar sus aplicaciones sin necesidad de ser expertos en seguridad. Auth0 implementa todos los flujos de OAuth 2.0, así como otros servicios adicionales.

El Universal Login de Auth0 permite a los usuarios autenticarse a través de los widgets de Auth0 Lock alojados en el sitio de Auth0, lo que aumenta la seguridad. Una de sus ventajas es el Single Sign On (SSO), lo que significa que un usuario solo tiene que autenticarse una vez para acceder a múltiples cuentas y plataformas. Este tipo de servicio es similar al que se utiliza al administrar cuentas de Google, donde se puede acceder a diferentes servicios (como Gmail, YouTube, entre otros) con una única sesión.

Social Login es una forma de implementar Single Sign-On (SSO) para usuarios finales utilizando información existente de un proveedor de redes sociales como Facebook, Twitter o Google. Esto permite a los usuarios acceder a sitios web de terceros sin tener que crear nuevas cuentas específicas para cada sitio web. Esta práctica simplifica el registro y acceso de los usuarios.

Referencias:

https://platzi.com/cursos/autenticacion-oauth/
https://www.oauth.com/oauth2-servers/server-side-apps/authorization-code/

Comentarios