El flujo OAuth 2.0 comienza cuando un usuario (dueño del recurso) interactúa con una aplicación cliente (cliente) y pide acceso a un recurso específico. EL cliente redirige al usuario a un servidor de autorización, donde se le pide al usuario que inicie sesión y otorgar acceso. Si el usuario consiente, el servidor de autorización emite un código de autentificación, el cual el cliente puede intercambiar por un token de acceso. Este token permite al cliente acceder al servidor de recursos y obtener el recurso pedido en nombre del usuario.

Veremos ahora los pasos del flujo de trabajo de OAuth en detalle, considerando el mismo ejemplo de la cafetería.
Conectarse a la Máquina
Le damos a "Start Machine" y esperamos 1-2 minutos. Tenemos que ir al archivo /etc/hosts y añadir la entrada <IP_tun0> cofee.thm bistro.thm.
Usaremos una versión personalizada de Django OAuth. FactBook el el proveedor OAuth. Puedes visitar http://coffee.thm:8000/admin para ver el panel de inicio de sesión del proveedor OAuth, que seguirá siendo el mismo a lo largo de la sesión.

Usaremos las siguientes credenciales para esta tarea:
- Víctima:
victim:victim123 - Atacante:
attacker:tesla@123
No es necesario que inicies sesión todavía.
Una vez inicies sesión en el proveedor OAuth, puedes iniciar sesión en cualquier otra página web, como harías con Sign Up with Google en X, Facebook o cualquier otra página.
Ahora visita http://bistro.thm:8000/, la cual usaremos para comprender el flujo de trabajo de OAuth. Entenderemos el flujo consideramdo a una persona llamada Tom, quien quiere iniciar sesión en una página diferente usando su cuenta de CoffeeShopApp.
Petición de Autorización
Tom visita primero bistro.thm, donde quiere iniciar sesión via CoffeeShopApp. Cuando hace click en "Login via OAuth", CoffeeShopApp debe primero obtener su permiso, por lo que la aplicación redirige a su navegador al servidor de autorización con una petición de autorización.

Si haces click en "Login with OAuth", serás redirigido al servidor de autorización con la URL http://coffee.thm:8000/accounts/login/?next=/o/authorize/%3Fclient_id%3Dzlurq9lseKqvHabNqOc2DkjChC000QJPQ0JvNoBt%26response_type%3Dcode%26redirect_uri%3Dhttp%3A//bistro.thm%3A8000/oauthdemo/callback, como se muestra debajo:

El sitio web del bistro inicia este proceso redirigiendo a Tom al servidor de autorización con los siguientes parámetros incluidos en la URL:
response_type=code: Esto indica queCoffeeSopAppespera un código de autorización como respuesta.state: Un token CSRF para asegurar que la petición y respuesta son parte de la misma transacción.client_id: Un identificador público para la aplicación del cliente, identificando de forma única aCoffeeShopApp.redirect_uri: La URL donde el servidor de autorización mandará a Tom después de que otorgue permiso. Debe coincidir con una de las URIs preregistradas para la aplicación del cliente.scope: Especifica el nivel de acceso pedido, como ver pedidos de café.
Incluyendo estos parámetros, la app del bistro se asegura de que el servidor de autorización entiende lo que se le está pidiendo y dónde mandar al usuario después. Aquí está el código de Python que redirige al usuario al servidor de autorización.
def oauth_login(request): app = Application.objects.get(name="CoffeeApp") redirect_uri = request.GET.get("redirect_uri", "http://bistro.thm:8000/oauthdemo/callback") authorization_url = ( f"http://coffee.thm:8000/o/authorize/?client_id={app.client_id}&response_type=code&redirect_uri={redirect_uri}" ) return redirect(authorization_url)
Autentificación y Autorización
Cuando Tom llega al servidor de autorización, se le pide iniciar sesión usando sus credenciales. Este paso asegura que el servidor pueda verificar su identidad. Después de haber iniciado sesión correctamente, el servidor de autorización le pregunta a Tom si accede a permitir a la app del bistro a acceder a sus detalles. Este paso de consentimiento es crucial, ya que le da a Tom transparencia y control sobre qué aplicaciones pueden acceder a su información.
Este proceso típicamente envuelve:
-
User Login: Tom introduce su nombre de usuario y contraseña en el login del servidor de autorización.
-
Consent Prompt: Después de la autentificación, el servidor de autorización le presenta a Tom una pantalla de consentimiento detallando a qué pide acceso
CoffeeShopApp. Tom debe decidir si acepta o deniega dichos permisos.
Este doble paso asegura que la identidad de Tom esté autentificada y que su consentimiento explícito es obtenido antes de que se otorgue cualquier acceso, manteniendo la seguridad y el control del usuario sobre su información personal.
Respuesta de Autorización
Si Tom acepta otorgar acceso, el servidor de autorización genera un código de autorización, como le pide la petición. El servidor entonces redirige a Tom al sitio del bistro usando la redirect_uri especificada. La redirección incluye el código de autorización y el parámetro state original para asegurar la integridad del flujo.
El servidor de autorización responde con:
code:CoffeeShopAppusará el código de autorización para pedir un token de acceso.state: El token CSRF previamente mandado porCoffeeShopApppara validar la respuesta.
Un ejemplo de respuesta sería: https://bistro.thm:8000/callback?code=AuthCode123456&state=xyzSecure123.
Este paso asegura que el proceso de autorización sea seguro y que la respuesta esté ligada a la petición inicial del bistro. El código de autorización es un token temporal que será usado en el próximo paso para obtener un token de acceso, permitiendo a CoffeeShopApp acceder a los detalles del perfil de Tom.
Petición del Token
El sitio web del bistro intercambia el código de autorización por un token de acceso haciendo una petición POST al endpoint token del servidor de autorización con los siguientes parámetros:
grant_type: Tipo de permiso que se usa, normalmente declarado comocodepara especificar código de autorización como tipo de permiso.code: El código de autorización obtenido del servidor de autorización.redirect_uri: Debe coincidir con la URI de redirección original dada en la petición de autorización.client_idyclient_secret: Credenciales para autentificar la aplicación del cliente.
Usando los parámetros de arriba, el siguiente código hará una petición de token al endpoint /o/token.
token_url = "http://coffee.thm:8000/o/token/" client_id = Application.objects.get(name="CoffeeApp").client_id client_secret = Application.objects.get(name="CoffeeApp").client_secret redirect_uri = request.GET.get("redirect_uri", "http://bistro.thm:8000/oauthdemo/callback") data = { "grant_type": "authorization_code", "code": code, "redirect_uri": redirect_uri, "client_id": client_id, "client_secret": client_secret, } headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': f'Basic {base64.b64encode(f"{client_id}:{client_secret}".encode()).decode()}', } response = requests.post(token_url, data=data, headers=headers) tokens = response.json()
La app del bistro intercambia de forma segura el código de autorización por un token de acceso mandando esta petición. El servidor de autorización verificará la información ofrecida, asegurando que la petición es válida y se origina del cliente pidiendo el código de autorización. Si todo es correcto, el servidor de autorización responderá con el token de acceso, permitiendo al sitio del bistro proceder a acceder a los detalles del perfil de Tom.
Respuesta del Token
El servidor de autorización autentifica la web del bistro y valida el código de autorización. Al validarse exitosamente, el servidor responde con un Access Token y, opcionalmente un Refresh Token.
La respuesta del servidor de autorización incluye lo siguiente:
access_token: Token que será usado para acceder a los detalles de Tom.token_type: Típicamente "Bearer".expires_in: La duración en segundos para la que el token de acceso es válido.refresh_token (opcional): Un token usado para obtener un nuevo token de acceso sin requerir que el usuario vuelva a iniciar sesión.
Con el token de acceso, el sitio web del bistro puede hacer peticiones autentificadas al servidor de recursos para acceder a los detalles de perfil de Tom. El token de refresco opcional puede usarse para pedir un nuevo token de acceso una vez que el actual expira, ofreciendo una mejor experiencia de usuario al hacer que Tom no tenga que volver a iniciar sesión cuando su token expira.
