Autorización con OAuth2

Compartir

Autorización con OAuth2

En el post de esta semana he decidido escribir sobre uno de los protocolos de autorización más utilizados en la web, se trata de OAuth2.

Cuando pensamos en otorgar accesos a una aplicación o API securizadas, lo primero que se nos viene a la mente son las credenciales de usuario (username y pasword).

El problema aquí surge cuando diferentes aplicaciones necesitan acceder a las APIs securizadas de otra aplicación, en tal caso, tendrían que estar solicitando las credenciales al usuario cada vez que se requieran consultar las APIs, (por ejemplo una aplicación que requiera acceder al listado de contactos de un usuario de Google).

Además de lo anterior, surgen algunos otros problemas derivados de esta implementación, algunos de ellos son:

Los usuarios podrían no confiar en tu aplicación para ingresar las credenciales requeridas.

El usuario al confiar en diferentes páginas para ingresar sus credenciales, es más susceptible a ataques de phishing.

Si el usuario ingresa sus credenciales a la aplicación, se podría tener control de toda su cuenta de usuario, y no solamente acceso a las APIs que se requieran utilizar.

Esos son algunos de los problemas con las credenciales, y son más que suficientes para tener que pensar en una mejor forma de manejar la autorización.

OAuth2 introduce la utilización de bearer tokens (o tokens al portador).

La utilización de este protocolo requiere en primera instancia que la aplicación (la llamaremos aplicación A) que necesita acceder a las APIs de una aplicación securizada (la llamaremos aplicación B) sea registrada en el servidor de autorización.

El servidor de autorización, es el servidor que maneja los accesos, y puede ser el mismo donde se encuentran las APIs, o un servidor externo (Auth0, Keycloac, Google, etc.).

Aquí podemos ver la pantalla donde se registra un cliente para acceder a las APIs de Google:

Luego que el registro es completado, se le entrega al desarrollador las credenciales del cliente para la aplicación registrada:

cliend_id: Identificador de la aplicación que requerirá acceder a los recursos en representación del usuario (el usuario es el dueño de la cuenta en la aplicación que expone las APIs securizadas).

client_secret: Código utilizado en ciertos flujos específicos de OAuth2, para la obtención de un access token y refresh token.

El hecho de registrar la aplicación, también mejora la experiencia de usuario, ya que parte de la información ingresada en el registro, es la que se muestra después cuando la aplicación A, requiere acceder a las APIs de la aplicación B, en la típica ventana que muestra una advertencia de que se está intentando acceder a ciertos recursos, para que el usuario dé la autorización:

Access Tokens (bearer token):

Son un tipo de token de acceso, mediante el cual, el simple hecho de poseerlo, proveerá acceso a los recursos protegidos

● Independiente del tipo de aplicación, el objetivo de la autorización mediante OAuth 2 es el mismo:

Obtener un access token que la aplicación A pueda utilizar para realizar las llamadas a las APIs protegidas de la aplicación B, en representación de un usuario o de la aplicación misma.

● Una vez obtenido el access token, éste puede ser enviado en las solicitudes a las APIs de variadas formas (Query parameter, Form Encoded body parameter, HTTP Authorization header)

Cada aplicación cliente, independiente de su perfil (server-side, client-side, o aplicación nativa), debe adaptarse a una forma específica de obtener el token de autorización (la forma en la cual interactuará la aplicación A con el servidor de autorización, para obtener un token de manera de poder consumir las APIs securizadas de la aplicación B).

El core de OAuth 2 define 4 flujos primarios para obtener la autorización (grant types):

Authorization Code

Apropiado para aplicaciones web de tipo “server side”, (por ejemplo aplicaciones PHP, o JSF)

Implicit Grant (browser-based client-side applications)

Es el flujo más simple de todos, y está optimizado para aplicaciones de tipo client-side ejecutándose en el navegador (por ejemplo Angular)

Resource Owner Password-Based Grant

Este flujo permite intercambiar las credenciales del usuario, por un access token. Es utilizado únicamente por clientes altamente confiables (ej.: App Mobile desarrollada por el API Provider)

Client Credentials

Permite a la aplicación cliente, obtener un access token para acceder a recursos de los cuales es dueña la misma aplicación cliente, o cuando la autorización ha sido previamente acordada con el servidor de autorización. Apropiado para aplicaciones que necesitan acceder a APIs (ej.: bases de datos, servicios de almacenamiento, etc.) en forma directa, en representación de sí mismos, más que en representación de un usuario específico

Para profundizar más en los flujos mencionados, pueden acceder a la página del RFC 6749 que describe el “OAuth 2.0 Authorization Framework”:


https://tools.ietf.org/html/rfc6749#page-8

Como podemos ver, a grandes rasgos, la utilización de OAuth2 consiste en los siguientes pasos:

1.- Tenemos una aplicación A que quiere acceder a recursos (APIs) de una aplicación B

2.- Los recursos de la aplicación B, están protegidos por un servidor de autorización que maneja el protocolo OAuth2

3.- El usuario de la aplicación A, que también tiene acceso a la aplicación B (tiene una cuenta de usuario), da la orden al servidor de autorización para que genere un Access Token y lo devuelva a la aplicación B (para dar la orden, el usuario debe haber iniciado sesión en el servidor de autorización)

4.- La aplicación B mediante la utilización del Access Token puede acceder a ciertos recursos específicos

Obviamente el protocolo OAuth2 tiene muchas más opciones que las que se muestran en este artículo, pero la idea fué explicar a grandes rasgos lo fundamental del protocolo, para que sirva como idea general de su funcionamiento.

Espero haber logrado el objetivo :D, hasta la próxima!