No sé si solo tengo algún tipo de punto ciego o qué, pero he leído las especificaciones de OAuth 2 muchas veces y he leído los archivos de la lista de correo, y todavía no he encontrado una buena explicación de por qué la Subvención implícita Se ha desarrollado un flujo para obtener tokens de acceso. En comparación con la concesión del código de autorización, parece simplemente renunciar a la autenticación del cliente sin una razón muy convincente. ¿Cómo se "optimiza para clientes implementados en un navegador usando un lenguaje de script" (para citar la especificación)?
Ambos flujos comienzan igual (fuente: http://tools.ietf.org/html/draft-ietf-oauth-v2-22 ):
- El cliente inicia el flujo dirigiendo el agente de usuario del propietario del recurso al punto final de autorización.
- 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.
- Asumiendo que el propietario del recurso concede acceso, el servidor de autorización redirige al agente de usuario nuevamente al cliente utilizando el URI de redireccionamiento proporcionado anteriormente (en la solicitud o durante el registro del cliente).
- El URI de redireccionamiento incluye un código de autorización (flujo de código de autorización)
- El URI de redireccionamiento incluye el token de acceso en el fragmento de URI (flujo implícito)
Aquí es donde se dividen los flujos. En ambos casos, el URI de redireccionamiento en este punto es a algún punto final alojado por el cliente:
- En el flujo del código de autorización, cuando el agente de usuario alcanza ese punto final con el código de autorización en el URI, el código en ese punto final intercambia el código de autorización junto con sus credenciales de cliente por un token de acceso que luego puede usar según sea necesario. Podría, por ejemplo, escribirlo en una página web a la que pueda acceder un script en la página.
- El flujo implícito omite este paso de autenticación del cliente por completo y solo carga una página web con el script del cliente. Aquí hay un lindo truco con el fragmento de URL que evita que el token de acceso se pase demasiado, pero el resultado final es esencialmente el mismo: el sitio alojado por el cliente sirve una página con algún script que puede tomar el token de acceso .
De ahí mi pregunta: ¿qué se ha ganado aquí omitiendo el paso de autenticación del cliente?
fuente
Respuestas:
Aquí están mis pensamientos:
El propósito del código de autenticación + token en el flujo del código de autorización es que el secreto del token y del cliente nunca se expondrá al propietario del recurso porque viajan de servidor a servidor.
Por otro lado, el flujo de concesión implícito es para clientes que se implementan completamente usando JavaScript y se ejecutan en el navegador del propietario del recurso. No necesita ningún código del lado del servidor para usar este flujo. Entonces, si todo sucede en el navegador del propietario del recurso, ya no tiene sentido emitir código de autenticación y secreto del cliente, porque el token y el secreto del cliente aún se compartirán con el propietario del recurso. La inclusión del código de autenticación y el secreto del cliente solo hace que el flujo sea más complejo sin agregar más seguridad real.
Entonces, la respuesta sobre "¿qué se ha ganado?" es "simplicidad".
fuente
Auth code
, junto conclient_id
yclient_secret
se utilizan para identificar clientes confiables que pueden actualizar tokens para un inicio de sesión prolongado y para "inicio de sesión sin conexión" . Sin embargo, en una aplicación del lado del cliente, no hay forma de registrar a cada cliente, de ahí el tipo de concesión implícita "simplificada" para el acceso temporal a la información del usuarioEstá ahí por razones de seguridad, no por simplicidad.
Debe considerar la diferencia entre el agente de usuario y el cliente :
El agente de usuario es el software mediante el cual el usuario ("propietario del recurso") se comunica con otras partes del sistema (servidor de autenticación y servidor de recursos).
El cliente es el software que desea acceder a los recursos del usuario en el servidor de recursos.
En el caso de cliente-agente y cliente desacoplados, la concesión del código de autorización tiene sentido. Por ejemplo, el usuario utiliza un navegador web (agente de usuario) para iniciar sesión con su cuenta de Facebook en Kickstarter. En este caso, el cliente es uno de los servidores de Kickstarter, que maneja los inicios de sesión de los usuarios. Este servidor obtiene el token de acceso y el token de actualización de Facebook. Por lo tanto, este tipo de cliente se considera "seguro", debido al acceso restringido, los tokens se pueden guardar y Kickstarter puede acceder a los recursos de los usuarios e incluso actualizar los tokens de acceso sin interacción del usuario.
Si el agente de usuario y el cliente están acoplados (por ejemplo, aplicación móvil nativa, aplicación javascript), se puede aplicar el flujo de trabajo de autorización implícita . Se basa en la presencia del propietario del recurso (para ingresar las credenciales) y no admite tokens de actualización. Si este cliente almacena el token de acceso para su uso posterior, será un problema de seguridad, ya que el token puede ser extraído fácilmente por otras aplicaciones o usuarios del cliente. La ausencia del token de actualización es una pista adicional, que este método no está diseñado para acceder a los recursos del usuario en ausencia del usuario.
fuente
La explicación habitual es que la concesión implícita es más fácil de implementar cuando está utilizando un cliente JavaScript. Pero creo que esta es la forma incorrecta de verlo. Si está utilizando un cliente JavaScript que solicita recursos protegidos directamente a través de XMLHttpRequest, la concesión implícita es su única opción, aunque es menos segura. *
La concesión del Código de autorización proporciona seguridad adicional, pero solo funciona cuando tiene un servidor web que solicita los recursos protegidos. Dado que el servidor web puede almacenar el token de acceso, corre menos riesgo de que el token de acceso esté expuesto a Internet, y puede emitir un token que dura mucho tiempo. Y dado que el servidor web es de confianza, se le puede dar un "token de actualización", para que pueda obtener un nuevo token de acceso cuando caduque el anterior.
Pero, y este es un punto fácil de pasar por alto, la seguridad del flujo del código de Autorización funciona solo si el servidor web está protegido con una sesión, que se establece con la autenticación del usuario (inicio de sesión). Sin una sesión, un usuario que no sea de confianza solo podría realizar solicitudes al servidor web, utilizando client_id, y sería lo mismo que si el usuario tuviera el token de acceso. Agregar una sesión significa que solo un usuario autenticado puede acceder a los recursos protegidos. Client_id es solo la "identidad" de la aplicación web JS, no la autenticación de dicha aplicación web.
También significa que puede finalizar la sesión antes de que caduque el token OAuth. No hay una forma estándar de invalidar un token de acceso. Pero si su sesión caduca, el token de acceso es inútil, ya que nadie lo sabe excepto el servidor web. Si un usuario que no es de confianza obtuvo acceso a su clave de sesión, solo podrá acceder a los recursos protegidos mientras la sesión sea válida.
Si no hay un servidor web, debe usar la concesión implícita. Pero esto significa que el token de acceso está expuesto a Internet. Si un usuario no confiable obtiene acceso a él, puede usarlo hasta que caduque. Esto significa que tendrán acceso a él por más tiempo que con una subvención del Código de autorización. Por lo tanto, es posible que desee considerar hacer que el token caduque antes y evitar dar acceso a recursos más confidenciales.
* EDITAR: más recientemente, las personas recomiendan que evites usar la concesión implícita, incluso en aplicaciones web sin un servidor. En su lugar, puede usar la concesión de Código de autorización configurada con un secreto vacío, junto con PKCE. La concesión de código de autenticación evita almacenar el token de acceso en el historial de su navegador, y PKCE evita exponerlo si alguien secuestra la URL de redireccionamiento para robar el código de autenticación. En este caso, necesitará que el servidor evite devolver un token de actualización, ya que su cliente probablemente no pueda almacenarlo de forma segura. Y debería emitir un token de acceso con las mismas limitaciones mencionadas anteriormente.
fuente
Se reduce a: si un usuario está ejecutando una aplicación web (JavaScript) basada en navegador o "pública" sin componente del lado del servidor, entonces el usuario confía implícitamente en la aplicación (y el navegador donde se ejecuta, potencialmente con otro navegador basadas en aplicaciones ...).
No hay un servidor remoto de terceros, solo el servidor de recursos. No hay ningún beneficio en un código de autorización, porque no hay otro agente además del navegador que actúe en nombre del usuario. No hay beneficio para las credenciales del cliente por la misma razón. ( Cualquier cliente puede intentar usar este flujo).
Las implicaciones de seguridad, sin embargo, son significativas. De http://tools.ietf.org/html/rfc6749#section-10.3 :
De http://tools.ietf.org/html/rfc6749#section-10.16 :
fuente
No estoy seguro de entender correctamente la respuesta y el comentario de Dan. Me parece que la respuesta ha declarado algunos hechos correctos, pero señala exactamente lo que OP preguntó. Si entiendo correctamente, la principal ventaja del flujo de concesión implícito es que un cliente como la aplicación JS (por ejemplo, la extensión de Chrome) no tiene que exponer el secreto del cliente.
Dan Taflin dijo:
Quizás te haya entendido mal, pero el cliente (aplicación JS en este caso) debe pasar la credencial del cliente (clave y secreto del cliente) al servidor de recursos en el flujo del código de autorización, ¿verdad? El secreto del cliente no se puede "guardar de JS".
fuente
Si bien la concesión implícita se diseñó para admitir aplicaciones que no podían proteger el secreto de un cliente, incluidas las aplicaciones JavaScript del lado del cliente, algunos proveedores están implementando una alternativa que utiliza el código de autorización sin un secreto de cliente. El OAuth 2.0 IETF RFC-6749 se publicó en 2012 y las recomendaciones actuales son algunas de las discusiones recientes de 2017.
La discusión de 2017 sobre la lista de correo IETF OAuth está disponible en estos implementadores:
Leer más aquí:
Aquí también se menciona el paso a Código de autenticación sin secreto de cliente desde Grant implícito para aplicaciones móviles:
fuente
Además de las otras respuestas, también es importante darse cuenta de que el perfil implícito permite un flujo de solo canal frontal en lugar del flujo del código de autorización que requiere una llamada al servidor de autorización; Esto se hace evidente en OpenID Connect, que es un protocolo SSO construido sobre Auth 2.0 donde el flujo implícito se asemeja al enlace SAML POST bastante popular y el flujo del código de autorización se asemeja al enlace de artefactos SAML menos implementado
fuente
En el flujo implícito, si el navegador del usuario está dañado (extensión / virus malvado), entonces la corrupción obtiene acceso a los recursos del usuario y puede hacer las cosas malas.
En el flujo de autenticación, la corrupción no puede porque no conoce el secreto del cliente.
fuente
https://tools.ietf.org/html/rfc6749#page-8
fuente
Creo que Will Cain respondió esto cuando dijo "No hay ningún beneficio para las credenciales del cliente por la misma razón. (Cualquier cliente puede intentar usar este flujo)." También considere que el redirect_uri para flujo implícito puede ser "localhost" - sin devolución de llamada se realiza desde el servidor de autorización para el flujo implícito. Como no hay forma de confiar previamente en el cliente, el usuario tendría que aprobar la liberación de las reclamaciones del usuario.
fuente
La concesión implícita permite obtener tokens del punto final de autorización con a
GET
. Esto significa que el servidor de autorización no tiene que admitir CORS.Si eso no es una preocupación y no hay otros problemas relacionados con el servidor de autorización inflexible (por ejemplo, los tokens de actualización no son opcionales, por alguna razón), el flujo de código de autorización es el preferido, incluso para clientes públicos, de acuerdo con las tendencias recientes de la industria y al menos a esta (actual) instancia de un borrador oficial .
Históricamente, hubo otras razones para implementar el flujo implícito, pero parece que actualmente son superadas por las ventajas de seguridad que brinda la concesión del código de autorización, que incluyen:
fuente
Acabo de enfrentar un artículo sobre OAuth 2.0. El autor afirma que la razón detrás del flujo implícito es que las aplicaciones JS estaban muy restringidas en sus solicitudes:
https://medium.com/securing/what-is-going-on-with-oauth-2-0-and-why-you-should-not-use-it-for-authentication-5f47597b2611
fuente