OAuth 2.0 - Lo bueno, lo malo y lo feo

En un mundo dominado por las redes sociales, es difícil no encontrar una aplicación cliente que haya usado para acceder a recursos restringidos en algún otro servidor, por ejemplo, podría haber usado una aplicación basada en web (como NY Times) para compartir una Un interesante artículo de noticias en tu muro de Facebook o tuitea sobre él. O bien, es posible que haya utilizado la aplicación de iPhone de Quora que accede a su perfil de Facebook o Google+ y personaliza los resultados según sus datos de perfil, como sugerir agregar / invitar a otros usuarios a Quora, según su lista de amigos. La pregunta es, ¿cómo obtienen acceso estas aplicaciones a sus cuentas de Facebook, Twitter o Google+ y cómo pueden acceder a sus datos confidenciales? Antes de que puedan hacerlo, deben presentar algún tipo de credenciales de autenticación y concesiones de autorización al servidor de recursos..


Introducción a OAuth 2.0

OAuth se describe a menudo como una clave de valet para la web.

Ahora, sería realmente nada sofisticado para compartir sus credenciales de Facebook o Google con cualquier aplicación cliente de terceros que solo necesite conocer a sus amigos, ya que no solo le da a la aplicación acceso ilimitado e indeseable a su cuenta, sino que también tiene la debilidad inherente asociada con las contraseñas. Aquí es donde OAuth entra en juego, ya que describe un marco de autorización / delegación de acceso que puede emplearse sin la necesidad de compartir contraseñas. Por esta razón, OAuth se describe a menudo como una clave de valet para la web. Se puede considerar como una llave especial que permite el acceso a funciones limitadas y por un período de tiempo limitado sin otorgar el control total, al igual que la llave de valet para un automóvil permite al operador de estacionamiento conducir el automóvil por una corta distancia, bloqueando Acceso al maletero y al móvil a bordo..

Sin embargo, OAuth no es un concepto nuevo, sino una estandarización y sabiduría combinada de muchos protocolos bien establecidos. También vale la pena señalar que OAuth no se limita a las aplicaciones de medios sociales, sino que proporciona una forma estandarizada de compartir información de manera segura entre varios tipos de aplicaciones que exponen sus API a otras aplicaciones. OAuth 2.0 tiene una prosa completamente nueva y no es compatible con las especificaciones anteriores. Dicho esto, sería bueno cubrir primero un vocabulario básico de OAuth2.0 antes de profundizar en más detalles.

  • Propietario del recurso : Una entidad capaz de otorgar acceso a un recurso protegido. La mayoría de las veces, es un usuario final..
  • Cliente : Una aplicación que realiza solicitudes de recursos protegidos en nombre del propietario del recurso y con su autorización. Puede ser una aplicación de escritorio, móvil (nativa) o basada en servidor..
  • Servidor de recursos : El servidor que aloja los recursos protegidos, capaz de aceptar y responder a solicitudes de recursos protegidos.
  • Servidor de Autorización : El servidor que otorga acceso otorga / tokens al cliente después de autenticar con éxito el propietario del recurso y obtener la autorización.
  • Token de acceso : Los tokens de acceso son credenciales presentadas por el cliente al servidor de recursos para acceder a los recursos protegidos. Normalmente es una cadena que consta de un alcance específico, vida útil y otros atributos de acceso y puede contener la información de autorización de manera verificable..
  • Actualizar el token : Aunque no están obligados por la especificación, los tokens de acceso tienen idealmente un tiempo de caducidad que puede durar desde unos pocos minutos hasta varias horas. Una vez que el token de acceso ha caducado, el cliente puede solicitar al servidor de autorización que emita un nuevo token de acceso utilizando el token de actualización emitido por el servidor de autorización..

Qué está mal con OAuth 1.0?

El mayor inconveniente de OAuth 1.0 fue la complejidad inherente necesaria para implementar la especificación.

¡Nada en realidad! Twitter aún funciona perfectamente bien con OAuth 1.0 y acaba de comenzar a admitir una pequeña parte de la especificación 2.0. OAuth 1.0 fue una especificación bien pensada y permitió el intercambio de información secreta de forma segura sin la sobrecarga impuesta por SSL. La razón por la que necesitábamos una renovación se basaba principalmente en la complejidad que enfrentaba al implementar la especificación. Las siguientes son algunas de las áreas donde OAuth 1.0 no pudo impresionar:

  • Firmando cada solicitud : Hacer que el cliente genere firmas en cada solicitud de API y validarlas en el servidor cada vez que se recibe una solicitud, demostró ser un gran revés para los desarrolladores, ya que tenían que analizar, codificar y ordenar los parámetros antes de realizar una solicitud. OAuth 2.0 eliminó esta complejidad simplemente enviando los tokens a través de SSL, resolviendo el mismo problema a nivel de red. No se requieren firmas con OAuth 2.0.
  • Direccionamiento de aplicaciones nativas : Con la evolución de las aplicaciones nativas para dispositivos móviles, el flujo basado en la web de OAuth 1.0 parecía ineficiente, lo que exigía el uso de agentes de usuario como un navegador web. OAuth 2.0 ha acomodado más flujos específicamente adecuados para aplicaciones nativas.
  • Separación clara de roles : OAuth 2.0 proporciona la muy necesaria separación de roles para que el servidor de autorización autentique y autorice al cliente, y el del servidor de recursos que maneja las llamadas a la API para acceder a recursos restringidos.

OAuth 2.0 en profundidad

Antes de iniciar el protocolo, el cliente debe registrarse en el servidor de autorización proporcionando su tipo de cliente, su URL de redirección (donde quiere que el servidor de autorización se redirija después de que el propietario del recurso otorgue o rechace el acceso) y cualquier otra información requerida por el servidor. y, a su vez, se le asigna un identificador de cliente (client_id) y un secreto de cliente (client_secret). Este proceso se conoce como Registro de clientes. Después de registrarse, el cliente puede adoptar uno de los siguientes flujos para interactuar con el servidor.

Varios flujos de OAuth

OAuth 2.0 trae alrededor de cinco nuevos flujos a la mesa y les brinda a los desarrolladores la flexibilidad de implementar cualquiera de ellos, dependiendo del tipo de cliente involucrado:

  • Flujo de usuario-agente : Adecuado para clientes que normalmente se implementan en agentes de usuario (por ejemplo, clientes que se ejecutan dentro de un navegador web) usando un lenguaje de scripting como JavaScript. Utilizado principalmente por aplicaciones nativas para dispositivos móviles o de escritorio, aprovecha el navegador integrado o externo como agente de usuario para la autorización y utiliza el Subvención implícita autorización.
  • Flujo del servidor web : Esto hace uso de la Código de Autorización otorgar y es un flujo basado en redireccionamiento que requiere interacción con el usuario-agente del usuario final. Por lo tanto, es más adecuado para clientes que forman parte de aplicaciones basadas en servidor web, a las que normalmente se accede a través de un navegador web.
  • Nombre de usuario y flujo de contraseña : Se utiliza solo cuando existe una alta confianza entre el cliente y el propietario del recurso y cuando otros flujos no son viables, ya que implica la transferencia de las credenciales del propietario del recurso. Ejemplos de clientes pueden ser un sistema operativo de dispositivo o una aplicación altamente privilegiada. Esto también se puede usar para migrar clientes existentes usando esquemas de autenticación de resumen o HTTP básicos a OAuth al convertir las credenciales almacenadas en un token de acceso.
  • Flujo de afirmación : Su cliente puede presentar una aserción como la aserción SAML al servidor de autorización a cambio de un token de acceso.
  • Flujo de credenciales del cliente : OAuth se usa principalmente para el acceso delegado, pero hay casos en que el cliente es propietario del recurso o ya se le ha otorgado el acceso delegado fuera de un flujo típico de OAuth. Aquí acaba de intercambiar credenciales de cliente por un token de acceso.

Discutir cada flujo en detalle estaría fuera del alcance de este artículo y preferiría leer la especificación para obtener información detallada sobre el flujo. Pero para tener una idea de lo que está pasando, profundicemos en uno de los flujos más utilizados y compatibles: el flujo del servidor web.

El flujo del servidor web

Dado que este es un flujo basado en la redirección, el cliente debe poder interactuar con el agente de usuario del propietario del recurso (que en la mayoría de los casos es un navegador web) y, por lo tanto, es típicamente adecuado para una aplicación web. El siguiente diagrama es una vista general de cómo el usuario final (o el propietario del recurso) utiliza la aplicación cliente (aplicación basada en servidor web en este caso) para autenticar y autorizar con el servidor de autorización, para acceder a los recursos protegidos. por el servidor de recursos.


Autenticar y autorizar al cliente

El cliente, en nombre del propietario del recurso, inicia el flujo redireccionando al punto final de autorización con un parámetro response_type como código, un identificador de cliente, que se obtiene durante el registro del cliente, una URL de redirección, un alcance solicitado (opcional) y un estado local (si corresponde). Para tener una idea de cómo funciona realmente, aquí hay una captura de pantalla de cómo se vería una solicitud / respuesta típica:


Esto normalmente presenta al propietario del recurso con una interfaz web, donde el propietario puede autenticarse y verificar qué permisos de la aplicación cliente pueden usar en su nombre..


Suponiendo que el propietario del recurso otorga acceso al cliente, el servidor de autorización redirige al agente de usuario al cliente utilizando la URL de redirección proporcionada anteriormente, junto con el código de autorización como se muestra en la respuesta a continuación.


Código de autorización de intercambio para tokens

El cliente entonces puestos a otro punto final de autorización y envía el código de autorización recibido en el paso anterior, junto con la URL de redirección, su identificador de cliente y su secreto, obtenidos durante el registro del cliente y un parámetro grant_type debe configurarse como Código de Autorización.


El servidor luego valida el código de autorización y verifica que la URL de redireccionamiento es la misma que en el paso anterior. Si tiene éxito, el servidor responde con un token de acceso y, opcionalmente, un token de actualización.


Solicitar recursos restringidos utilizando tokens de acceso

El cliente ahora puede consumir las API proporcionadas por la implementación y puede consultar el servidor de recursos para un recurso restringido pasando el token de acceso en el encabezado de autorización de la solicitud. Una solicitud CURL de muestra a la API de Blogger de Google para obtener un blog, dado su identificador, se vería así:

 $ curl https://www.googleapis.com/blogger/v3/blogs/5223788876950011016 -H 'Autorización: OAuth ya29.AHES6ZRTj1GNxAby81Es-p_YPWWNBAFRvBYVsYj2HZJfJHU'

Tenga en cuenta que hemos agregado el token de acceso como encabezado de autorización en la solicitud y también hemos evitado el token al incluirlo entre comillas simples, ya que el token puede contener caracteres especiales. Tenga en cuenta que para usar el toldo solo es necesario escapar del token de acceso. Da como resultado el envío de la siguiente solicitud:


El servidor de recursos luego verifica las credenciales pasadas (token de acceso) y, si tiene éxito, responde con la información solicitada..


Estos ejemplos son cortesía de OAuth2.0 Playground y son típicos de cómo Google implementa la especificación. Es posible que se observen diferencias al intentar el mismo flujo con otros proveedores (como Facebook o Salesforce) y es aquí donde surgen los problemas de interoperabilidad, que veremos más adelante..

Token de acceso refrescante

Aunque no es obligatorio por la especificación, pero por lo general los tokens de acceso son de corta duración y vienen con un tiempo de caducidad. Por lo tanto, cuando un token de acceso ha caducado, el cliente envía el token de actualización al servidor de autorización, junto con su identificador y secreto de cliente, y un parámetro grant_type como refresh_token.


El servidor de autorización responde luego con el nuevo valor para el token de acceso.


Aunque existe un mecanismo para revocar el token de actualización emitido, pero normalmente el token de actualización tiene vida y debe ser protegido y tratado como un valor secreto..


¿Qué está mal con OAuth 2.0??

Las buenas cosas

A juzgar por la tasa de adopción, OAuth 2.0 es definitivamente una mejora sobre su antecesor arcano. Las instancias de la comunidad de desarrolladores que fallan al implementar las firmas de 1.0 no son desconocidas. OAuth 2.0 también proporciona varios tipos de concesión nuevos, que se pueden usar para admitir muchos casos de uso como aplicaciones nativas, pero la USP de esta especificación es su simplicidad sobre la versión anterior..

Las partes malas

Hay algunos cabos sueltos en la especificación, ya que no define correctamente algunos componentes necesarios o los deja a las implementaciones para decidir, como por ejemplo:

Es probable que los extremos sueltos en la especificación OAuth 2.0 produzcan una amplia gama de implementaciones no interoperables.

  • Interoperabilidad: La adición de demasiados puntos de extensión en la especificación resultó en implementaciones que no son compatibles entre sí, lo que significa que no puede esperar escribir un fragmento de código genérico que use Descubrimiento de punto final para conocer los puntos finales proporcionados por las diferentes implementaciones e interactuar con ellos, en lugar de eso, tendría que escribir piezas de código separadas para Facebook, Google, Salesforce, etc. Incluso la especificación admite este fallo como un descargo de responsabilidad..
  • Fichas de Vida Corta: La especificación no exige la vida útil y el alcance de los tokens emitidos. La implementación es gratuita para tener un token en vivo para siempre. Aunque la mayoría de las implementaciones nos proporcionan tokens de acceso de corta duración y un token de actualización, que se puede utilizar para obtener un token de acceso nuevo.
  • Seguridad: La especificación simplemente "recomienda" el uso de SSL / TLS al enviar los tokens en texto sin formato a través del cable. Sin embargo, cada implementación importante ha hecho que sea necesario contar con puntos finales de autorización seguros, así como que el cliente debe tener una URL de redirección segura; de lo contrario, será demasiado fácil para un atacante espiar la comunicación y descifrar los tokens..

El esputo feo

Le tomó al IETF aproximadamente 31 versiones de borrador y la renuncia del autor / desarrollador principal Eran Hammer del comité para finalmente publicar la especificación. Eran provocó una controversia llamando a la especificación "Un mal protocolo y un caso de muerte por mil cortes".. Según él, el uso de tokens de portador (enviar tokens a través de SSL sin firmarlos o cualquier otra verificación) sobre el usuario de firmas (o token de MAC), utilizado en OAuth 1.0 para firmar la solicitud, fue un mal movimiento y un resultado de división de intereses entre la web y las comunidades empresariales..


Observaciones concluyentes

La especificación seguramente deja muchos puntos de extensión abiertos, lo que resulta en implementaciones que introducen sus propios parámetros, además de lo que la especificación ya define, y se asegura de que las implementaciones de diferentes proveedores no puedan interoperar entre sí. Pero al ir con la popularidad y la tasa de adopción de este marco, con cada gran jugador de la ciudad (Google, Twitter, Facebook, Salesforce, Foursquare, Github, etc.) implementándolo y ajustándolo de la forma que más le convenga, OAuth está lejos de ser un fracaso . De hecho, cualquier aplicación web que planee exponer sus API a otras aplicaciones web debe admitir algún tipo de autenticación y autorización, y OAuth encaja a la perfección aquí..

Para leer más

  • OAuth y el camino al infierno
  • OAuth - Una Introducción
  • RFC 5849 - especificación OAuth1.0
  • RFC 6749 - especificación OAuth2.0