¿Cuál es la diferencia entre el Código de autorización de OAuth y los flujos de trabajo implícitos? ¿Cuándo usar cada uno?

165

OAuth 2.0 tiene múltiples flujos de trabajo. Tengo algunas preguntas sobre los dos.

  1. Flujo de código de autorización : el usuario inicia sesión desde la aplicación cliente, el servidor de autorización devuelve un código de autorización a la aplicación. La aplicación luego intercambia el código de autorización por el token de acceso.
  2. Flujo de concesión implícito : el usuario inicia sesión desde la aplicación cliente, el servidor de autorización emite un token de acceso a la aplicación cliente directamente.

¿Cuál es la diferencia entre los dos enfoques en términos de seguridad? ¿Cuál es más seguro y por qué?

No veo una razón por la que se agrega un paso adicional (código de autorización de intercambio para token) en un flujo de trabajo cuando el servidor puede emitir directamente un token de acceso.

Diferentes sitios web dicen que el flujo de código de autorización se usa cuando la aplicación cliente puede mantener seguras las credenciales. ¿Por qué?

divyanshm
fuente

Respuestas:

204

Esto access_tokenes lo que necesita llamar un recurso protegido (una API). En el flujo del Código de autorización hay 2 pasos para obtenerlo:

  1. El usuario debe autenticarse y devolver un code al consumidor API (llamado "Cliente").
  2. El "cliente" de la API (generalmente su servidor web) intercambia el codeobtenido en el # 1 por un access_token, autenticándose con un client_idyclient_secret
  3. Luego puede llamar a la API con el access_token.

Entonces, hay una doble verificación: el usuario que posee los recursos surgió a través de una API y el cliente que usa la API (por ejemplo, una aplicación web). Ambos están validados para que se otorgue acceso. Observe la naturaleza de "autorización" de OAuth aquí: el usuario concede acceso a su recurso (a través de la codedevolución después de la autenticación) a una aplicación, la aplicación obtiene un access_tokeny llama en nombre del usuario.

En el flujo implícito, se omite el paso 2. Entonces, después de la autenticación del usuario, access_tokense devuelve un directamente, que puede usar para acceder al recurso. La API no sabe quién llama a esa API. Cualquiera con elaccess_token lata, mientras que en el ejemplo anterior solo la aplicación web lo haría (es interna normalmente no es accesible para nadie).

El flujo implícito generalmente se usa en escenarios donde se almacena client idy client secretno se recomienda (un dispositivo, por ejemplo, aunque muchos lo hacen de todos modos). Eso es lo que significa el descargo de responsabilidad. Las personas tienen acceso al código del cliente y, por lo tanto, pueden obtener las credenciales y pretender convertirse en clientes de recursos. En el flujo implícito, todos los datos son volátiles y no hay nada almacenado en la aplicación.

Eugenio Pace
fuente
Gracias por su explicación, pero no entiendo por qué necesitamos otro flujo de código de autorización. Podemos alcanzar el mismo resultado en el servidor por flujo implícito (access_token) y un token de actualización. Parece que la única consideración de seguridad del flujo implícito es que el código de acceso debe tener una vida corta, por lo que no se puede usar de servidor a servidor. OK, pero el token de actualización resuelve este problema. ¿Por qué deberíamos usar un flujo auth_code y solicitar access_token por ese en el servidor para obtener access_code?
Mohammad Nikravan
Bueno ... así es como funciona el protocolo. Es posible que desee leer el análisis de amenazas de especificaciones para obtener una referencia más detallada sobre los méritos de seguridad de uno y otro.
Eugenio Pace
Sé que la respuesta original tiene más de 5 años, pero esta es la explicación más simple y limpia que he leído. Gracias @EugenioPace
Taha Ahmad
1
@ Madnik7G La razón es ortogonal a lo que esto explica (bellamente): puede haber un tercero involucrado. Todo el flujo es orquestado por un agente de usuario (por ejemplo: el navegador), pero al final el servidor de autorización (por ejemplo: "Iniciar sesión con Facebook") hablará directamente con el cliente (por ejemplo, su BFF del lado del servidor) que en última instancia, acceda al recurso, de modo que el agente de usuario nunca tenga acceso directo.
Daniel Langdon
¡Gracias! Sí, hay 3 comunicaciones en curso: el navegador y el AS 9e.g. Facebook). Esa es la /authorizesolicitud. El navegador y el sitio web que intentan llamar a la API (también conocido como el cliente). Ese es el redirect_uri+ codedevuelto por el AS después de una autenticación exitosa. Finalmente, el cliente llama al AS detrás de escena, intercambiando el codepor un access_token. Este es el token endpointen la literatura. En general, el AS nunca llama a nadie. Siempre responde.
Eugenio Pace
52

Agregaré algo aquí que no creo que quede claro en las respuestas anteriores:

  • El flujo de código de autorización permite que el token de acceso final nunca llegue y nunca se almacene en la máquina con el navegador / aplicación . El código de autorización temporal se entrega a la máquina con el navegador / aplicación, que luego se envía a un servidor. El servidor puede intercambiarlo con un token de acceso completo y tener acceso a API, etc. El usuario con el navegador obtiene acceso a la API solo a través del servidor con el token.
  • El flujo implícito solo puede involucrar a dos partes, y el token de acceso final se almacena en el cliente con el navegador / aplicación. Si este navegador / aplicación se ve comprometido, también lo es su token de autenticación, que podría ser peligroso.

tl; dr no use el flujo implícito si no confía en la máquina de los usuarios para guardar tokens pero confía en sus propios servidores.

George Powell
fuente
12
re: El usuario con el navegador obtiene acceso a la API solo a través del servidor con el token. Pero el servidor necesita enviar algo al navegador para que las solicitudes entrantes puedan asociarse al token que se encuentra en el lado del servidor. Una galleta si quieres. Si el servidor no transmite el token al JS que se ejecuta en el navegador, debe transmitir algo más, que el cliente (navegador) debe pasar al servidor, para permitir que el servidor actúe en nombre del cliente en particular.
Cheeso
Si, una galleta. Por lo tanto, debe configurar su servidor y cliente de navegador para que esté protegido contra la falsificación de solicitudes entre sitios.
Marcel
@Marcel Me gustaría saber que una vez que obtengamos el código, cómo y dónde sucede el intercambio para obtener el real access_tokencon la ayuda de authorization code.
chirag soni
14

La diferencia entre ambos es que:

  1. En el flujo implícito, el token se devuelve directamente a través de la URL de redireccionamiento con el signo "#" y esto se usa principalmente en clientes javascript o aplicaciones móviles que no tienen el lado del servidor, y el cliente no necesita proporcionar su secreto en algunas implementaciones .

  2. En el flujo de código de autorización, el código se devuelve con "?" para ser legible por el lado del servidor, entonces el lado del servidor debe proporcionar el secreto del cliente esta vez a la URL del token para obtener el token como objeto json del servidor de autorización. Se usa en caso de que tenga un servidor de aplicaciones que pueda manejar esto y almacenar el token de usuario con su perfil en su propio sistema, y ​​se usa principalmente para aplicaciones móviles comunes.

por lo tanto, depende de la naturaleza de su aplicación cliente, cuál es un "Código de autorización" más seguro, ya que se solicita el secreto en el cliente y el token se puede enviar entre el servidor de autorización y la aplicación cliente en una conexión muy segura, y el proveedor de autorización puede restringir a algunos clientes a usar solo "Código de autorización" y no permitir lo implícito

Bassem Reda Zohdy
fuente
El código de autorización se almacena en el lado del servidor durante 10 minutos para Facebook. Esto fue lanzado en su cambio del 5 de diciembre de 2012. Mi pregunta es principalmente, ¿cuál es la diferencia entre los 2 en términos de seguridad / rendimiento? Sé lo que hacen ambos flujos, pero cuál es la ventaja de usar el código de autorización, agregando un paso más al flujo de trabajo.
divyanshm
no está enviando el token a la aplicación del usuario, la conexión entre la aplicación del cliente y el servidor de autorización está oculta para el usuario, y como mencioné, podría ser un canal muy seguro, no el mismo que el del usuario a la aplicación del cliente.
Bassem Reda Zohdy
el rendimiento en el código de Autorización golpea el servidor de autenticación dos veces, por lo que lleva más tiempo, también el servidor del cliente almacenará el token del usuario y esto también agregará más tiempo.
Bassem Reda Zohdy
2
¡Oh, está bien! Podría haber pasado por alto esto. Básicamente, el flujo de código de autorización debe ser utilizado por sistemas donde un servidor completo es un cliente: el navegador realiza la solicitud y obtiene el código. El código se envía al servidor del cliente que se conecta al servidor de recursos de forma segura. ¿Lo estoy entendiendo correctamente? ¿El token de acceso nunca llega a la máquina del usuario final?
divyanshm
1
¿El token de acceso nunca llega a la máquina del usuario final? Sí, está vinculado a su perfil con el servidor de aplicaciones del cliente.
Bassem Reda Zohdy
4

La concesión implícita es similar a la concesión del código de autorización con dos diferencias distintas.

Está destinado a ser utilizado por clientes basados ​​en agentes de usuario (por ejemplo, aplicaciones web de una sola página) que no pueden mantener en secreto a un cliente porque todo el código de la aplicación y el almacenamiento son fácilmente accesibles.

En segundo lugar, en lugar de que el servidor de autorización devuelva un código de autorización que se intercambia por un token de acceso, el servidor de autorización devuelve un token de acceso.

Encuentre los detalles aquí http://oauth2.thephpleague.com/authorization-server/which-grant/

Lutfor
fuente
1
Gracias por ese enlace, me ayudó a entender la diferencia entre cada tipo de subvención y cuándo elegir cada uno.
François POYER
3

Flujo implícito

Ventajas

  • Más simple de implementar

Desventajas

  • Fichas de acceso visibles para el navegador
  • El origen de los tokens de acceso no se puede determinar
  • Los tokens de acceso no pueden caducar (según la política de Google)

Flujo de código de autorización

Ventajas

  • Más seguro
  • Los tokens de acceso y los tokens de actualización solo se pueden crear si se conoce un secreto compartido
  • Se puede mejorar con nuevas funciones de seguridad y UX cuando estén disponibles

Desventajas

  • Debe implementar múltiples puntos finales de autenticación

Cita: https://developers.google.com/actions/develop/identity/oauth2-overview#supported_oauth_20_flows

vlazzle
fuente
2

Permítanme resumir los puntos que aprendí de las respuestas anteriores y agregar algunos de mis propios entendimientos.

Código de autorización de flujo !!!

  • Si tiene un servidor de aplicaciones web que actúa como cliente OAuth
  • Si quieres tener acceso de larga duración
  • Si desea tener acceso sin conexión a los datos
  • cuando eres responsable de las llamadas de API que hace tu aplicación
  • Si no quieres perder tu token OAuth
  • Si no desea que su aplicación se ejecute a través del flujo de autorización cada vez que necesita acceso a los datos. NOTA: El flujo de concesión implícita no entretiene el token de actualización, por lo que si el servidor de autorización vence los tokens de acceso regularmente, su aplicación deberá ejecutar el flujo de autorización cada vez que necesite acceso.

Subvención implícita de flujo!

  • Cuando no tiene un servidor de aplicaciones web para actuar como cliente OAuth
  • Si no necesita acceso de larga duración, es decir, solo se requiere acceso temporal a los datos.
  • Si confía en el navegador donde se ejecuta su aplicación y existe una preocupación limitada de que el token de acceso se filtre a usuarios no confiables.
Aman Tuladhar
fuente
2

¿Cuál es más seguro y por qué?

Ambos son seguros, depende del entorno que lo esté utilizando.

No veo una razón por la cual se agrega un paso adicional (código de autorización de intercambio para token) en un flujo de trabajo cuando el servidor puede emitir directamente un token de acceso.

Es simple. Tu cliente no es seguro. Vamos a verlo en detalles.

Considere que está desarrollando una aplicación en contra Instagram API, por lo que registra su aplicación Instagramy define cuál API'snecesita. Instagramle proporcionará client_idyclient_secrect

En su sitio web configura un enlace que dice. "Ven y usa mi aplicación". Al hacer clic en esto, su aplicación web debe realizar dos llamadas Instagram API.

Firstenvíe una solicitud a Instagram Authentication Servercon los siguientes parámetros.

1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token. 

No envíaclient_secret , no puede confiar en el cliente (el usuario y / o su navegador que intentan usar su aplicación). El cliente puede ver el script de url o java y encontrarlo client_secrectfácilmente. Por eso necesitas otro paso.

Recibe un codey state. El codeaquí está temporaryy no se guarda en ningún lado.

Luego haces una secondllamada a Instagram API(desde tu servidor)

 1. `grant_type` with the value of `authorization_code`
 2. `client_id` with the client identifier
 3. `client_secret` with the client secret
 4. `redirect_uri` with the same redirect URI the user was redirect back to
 5. `code` which we have already received.

A medida que la llamada se realiza desde nuestro servidor, podemos usar de forma segura client_secret(que muestra cómo estamos) con lo codeque muestra que el usuario ha concedido client_idusar el recurso.

En respuesta tendremos access_token

Alireza Fattahi
fuente
1

Desde una perspectiva práctica (lo que entendí), la razón principal para tener flujo de código Authz es:

  1. Soporte para tokens de actualización (acceso a largo plazo por aplicaciones en nombre del Usuario), no está implícito: consulte: https://tools.ietf.org/html/rfc6749#section-4.2
  2. Soporte para la página de consentimiento, que es un lugar donde el propietario del recurso puede controlar qué acceso proporcionar (tipo de permisos / página de autorización que ve en google). Lo mismo no está implícito. Vea la sección: https://tools.ietf.org/html/rfc6749#section-4.1 , punto (B)

"El servidor de autorización autentica al propietario del recurso (a través del agente de usuario) y establece si el propietario del recurso otorga o rechaza la solicitud de acceso del cliente"

Además de eso, al usar tokens de actualización, las aplicaciones pueden obtener acceso a largo plazo a los datos del usuario.

dvsakgec
fuente
0

Parece que hay dos puntos clave, no discutidos hasta ahora, que explican por qué el desvío en el Tipo de concesión del código de autorización agrega seguridad.

Breve historia : el tipo de concesión de código de autorización mantiene información confidencial del historial del navegador, y la transmisión del token depende solo de la protección HTTPS del servidor de autorización.

Versión más larga:

A continuación, seguiré con la terminología de OAuth 2 definida en el RFC (es una lectura rápida): servidor de recursos , cliente , servidor de autorización , propietario del recurso .

Imagine que desea que una aplicación de terceros (= cliente) acceda a ciertos datos de su cuenta de Google (= servidor de recursos). Supongamos que Google usa OAuth 2. Usted es el propietario de los recursos de la cuenta de Google, pero en este momento opera la aplicación de terceros.

Primero, el cliente abre un navegador para enviarlo a la URL segura del servidor de autorización de Google. Luego, aprueba la solicitud de acceso, y el servidor de autorización lo envía de regreso a la URL de redireccionamiento previamente proporcionada por el cliente, con el código de autorización en la cadena de consulta. Ahora para los dos puntos clave:

  1. La URL de esta redirección termina en el historial del navegador. . Por lo tanto, no queremos un token de acceso de larga duración y directamente utilizable aquí. El código de autorización de corta duración es menos peligroso en la historia. Tenga en cuenta que el tipo de subvención implícita no pone el token en la historia.
  2. La seguridad de esta redirección depende del certificado HTTPS del cliente. , no del certificado de Google. Entonces obtenemos la seguridad de transmisión del cliente como un vector de ataque adicional (para que esto sea inevitable, el cliente no debe tener JavaScript. De lo contrario, podríamos transmitir el código de autorización a través de un fragmento de URL, donde el código no pasaría por la red. esta puede ser la razón por la subvención implícita tipo, que hace uso de un fragmento de URL, que se utiliza para ser recomendado para los clientes de JavaScript, a pesar de que ya no es así.)

Con el Tipo de concesión de código de autorización, el token se obtiene finalmente mediante una llamada del cliente al servidor de autorización, donde la seguridad de la transmisión solo depende del servidor de autorización , no del cliente.

Carsten Führmann
fuente