OAuth2 ROPC vs autenticación básica para API REST públicas?


21

El caso de uso específico que me interesa aquí es la autenticación de clientes REST contra puntos finales de servidores disponibles públicamente (como una API REST pública).

La solución más simple aquí es la autenticación básica . Pero a menudo escucho a OAuth2 promocionado como una solución de autenticación superior en casi todas las circunstancias.

La cuestión es que el único tipo de concesión de OAuth2 que es factible para un cliente REST que se autentica en un servidor REST son las Credenciales de contraseña del propietario del recurso (ROPC) , porque las concesiones de código y las concesiones implícitas requieren una UI / página web (alojada por el servidor Auth) para usuario para iniciar sesión y autorizar manualmente la aplicación cliente.

La forma en que funciona ROPC es enviando el nombre de usuario / contraseña del propietario del recurso y la ID del cliente como parámetros de cadena de consulta . Esto es aún menos seguro (en mi humilde opinión) que la autenticación básica, que al menos en base 64 codifica las credenciales y las envía dentro de un encabezado que TLS puede cifrar.

Entonces, pregunto: en el contexto de las API REST públicas, ¿OAuth2 ROPC es realmente mejor que la autenticación básica? ¿Qué es más seguro que OAuth2 ROPC?


Actualizar

Acabo de leer este excelente artículo que explica la seguridad REST no basada en OAuth2 de Amazon para AWS. Es esencialmente una solución basada en clave privada donde los hashes de cada solicitud REST se generan y envían como sidecars junto con la solicitud normal (sin cifrar). Solo el cliente y el servidor conocen la clave privada, por lo que cuando el servidor recibe la solicitud (de nuevo, que contiene la solicitud normal + la solicitud hash), el servidor busca la clave privada del cliente, aplica el mismo hash a la solicitud normal y luego compara los dos hashes.

¡Esto suena mucho más complicado, complejo y seguro que el ROPC de OAuth2! A menos que me falte algo importante aquí, OAuth2 ROPC solo está enviando client_id, usernamey passwordcomo parámetros de cadena de consulta ... ¡total y completamente inseguro! Esta solución basada en HMAC / hash parece ser mucho más impresionante y segura.

La cuestión es que incluso el autor de ese artículo continúa diciendo:

Usted también se dará cuenta lentamente y aceptará que en algún momento tendrá que implementar OAuth ...

Ba-ba-bwhat?!?! Si OAuth2 es menos seguro que esta solución inteligente basada en HMAC / hash, ¿por qué el autor de este artículo siente que OAuth necesita ser aceptado en algún momento? Estoy tan confundida.


¿De qué tipo de cliente estás hablando? Supongo que la mayoría de los clientes tendrán una interfaz de usuario. En ese caso, puede cargar la página de inicio de sesión de OAuth en una vista web (escritorio, móvil) o redirigirla directamente (web). No veo por qué necesitas evitar la IU.
Decyclone

@decyclone, lea la primera oración de la pregunta. Estoy tomando sobre los clientes REST (HTTP sin cabeza) que se autentican contra los servicios REST.
smeeb

La pregunta que hago es si ese cliente tiene alguna interfaz de usuario. Incluso si no lo hubiera hecho, he visto aplicaciones sin interfaz de usuario abrir un cuadro de diálogo al menos para la autenticación.
deciclón el

@decyclone no es un cliente REST puro que no tiene ninguna interfaz de usuario, aunque las UI suelen utilizar un cliente REST puro para conectarse a un servicio REST. Un caso de uso es una herramienta de línea de comandos que utiliza un cliente REST para enviar comandos de usuario (ingresados ​​en el shell) al servicio REST. Hacer estallar una interfaz de usuario desde un shell simplemente no es una solución aceptable aquí.
smeeb

1
Pero, debo señalar, hay muchos otros casos de uso fuera de una línea de comandos / shell. Otro caso de uso es un cliente REST / HTTP puro Java / Ruby / Python que no tiene interfaz de usuario y podría estar ejecutándose en un servidor de fondo que no tiene interfaz de usuario. El servidor de fondo necesita comunicarse con otro servidor de fondo a través de REST. Aquí, no solo sería incómodo y hacky hacer estallar una interfaz de usuario cuando el servidor de back-end # 1 necesita hablar con el servidor de back-end # 2, el verdadero problema es que no hay un navegador / cliente de UI para mostrar la página de inicio de sesión, y no hay humanos estar allí para iniciar sesión!
smeeb

Respuestas:


24

La respuesta a su pregunta puede ser a nivel de código, protocolo o arquitectura. Intentaré resumir aquí la mayoría de los problemas de nivel de protocolo, ya que eso suele ser crítico en el análisis de pros y contras. Tenga en cuenta que OAuth2 es mucho más que Credenciales de contraseña de propietario de recursos que, según la especificación, existe por "razones heredadas o de migración", se considera "mayor riesgo que otros tipos de concesión" y la especificación establece explícitamente que los clientes y los servidores de autorización "DEBE minimizar el uso de este tipo de subvención y utilizar otros tipos de subvención siempre que sea posible".

Todavía hay muchas ventajas de usar ROPC sobre la autenticación básica, pero antes de entrar en eso, comprendamos la diferencia de protocolo básico entre OAuth2 y la autenticación básica. Por favor tengan paciencia conmigo mientras les explico esto y vendré a ROPC más tarde.

Flujos de autenticación de usuario

Hay cuatro roles definidos en la especificación OAuth2. Con ejemplos, son:

  1. Propietario del recurso: el usuario que tiene acceso a algún recurso, por ejemplo, en su caso, diferentes usuarios pueden tener diferentes niveles de acceso a la API REST;
  2. El cliente: generalmente la aplicación que está usando el usuario y necesita acceso al recurso para proporcionar servicios al usuario;
  3. Servidor de recursos: la API REST en su caso; y
  4. Servidor de autorización: el servidor en el que se presentan las credenciales del usuario y que autenticará al usuario.

Cuando se ejecuta una aplicación cliente, se le otorga acceso a los recursos en función del usuario. Si un usuario tiene privilegios de administrador, los recursos y las operaciones disponibles para el usuario en REST API pueden ser mucho más que un usuario sin privilegios de administrador.

OAuth2 también permite la posibilidad de utilizar un único servidor de autorización con múltiples clientes y para múltiples recursos. Como ejemplo, un servidor de recursos puede aceptar la autenticación del usuario con Facebook (que puede actuar como servidor de autorización en tal caso). Entonces, cuando el usuario ejecuta una aplicación (es decir, el cliente), envía al usuario a Facebook. El usuario escribe sus credenciales en Facebook y el cliente recupera un "token" que puede presentar al servidor de recursos. El servidor de recursos mira el token y lo acepta después de verificar que Facebook, de hecho, lo emitió y permite al usuario acceder al recurso. En este caso, el cliente nunca ve las credenciales del usuario (es decir, sus credenciales de Facebook).

Pero supongamos que está administrando las identidades de sus usuarios (y tiene un servidor de autorización) en lugar de Facebook, que ya le otorga tokens a su cliente. Ahora, supongamos que también tiene un socio y desea permitir que su aplicación (es decir, el cliente) acceda a su API REST. Con autenticación básica (o incluso ROPC), el usuario proporcionará credenciales a ese cliente que lo enviará al servidor de autorización. El servidor de autorización proporcionará un token que el cliente puede usar para acceder a los recursos. Desafortunadamente, esto significa que las credenciales del usuario ahora también son visibles para ese cliente. Sin embargo, no querrá que la aplicación de un socio (que podría ser externa a su organización) sepa siquiera la contraseña de un usuario. Eso es un problema de seguridad ahora. Para lograr ese objetivo,

Por lo tanto, con OAuth2, uno idealmente no usaría ROPC en tales casos, sino que usaría uno diferente, como el flujo de código de autorización. Esto protege a cualquier aplicación de conocer las credenciales del usuario que se presentan solo al servidor de autorización. Por lo tanto, las credenciales de un usuario no se filtran. Los mismos problemas se aplican con la autenticación básica, pero en la siguiente sección, explicaré cómo ROPC sigue siendo mejor porque las credenciales del usuario aún no necesitan ser almacenadas por el cliente en ROPC para el acceso persistente de los clientes.

Tenga en cuenta que cuando el usuario va al servidor de autorización, el servidor de autorización también puede pedirle al usuario que confirme que desea permitir que el cliente acceda a los recursos en su nombre o no. Es por eso que se llama el servidor de autorización porque el proceso de autorización de un cliente para acceder a los recursos está implicado en el proceso. Si el usuario no autoriza al cliente, no obtendrá acceso a los recursos. Del mismo modo, si el usuario no tiene acceso a los recursos, el servidor de autorización puede denegar el acceso y no emitir un token.

En la autenticación básica, incluso el servidor de autorización y el servidor de recursos se combinan en una sola entidad. Por lo tanto, el servidor de recursos quiere autorizar al usuario, por lo que solicita las credenciales del cliente. El cliente proporciona esas credenciales que utiliza el servidor de recursos para autenticar al usuario. Esto significa que múltiples servidores de recursos requerirán esencialmente credenciales del usuario.

Emisión de tokens

Los clientes obtienen tokens del servidor de autorización, los mantienen cerca y los usan para acceder a los recursos (más detalles sobre los tokens mismos a continuación). Los clientes nunca conocen la contraseña del usuario (en flujos que no sean ROPC) y no necesitan almacenarla. En ROPC, a pesar de que los clientes conocen la contraseña del usuario, aún no necesitan almacenarla porque usan estos tokens para acceder a los recursos. Por el contrario, en la autenticación básica, si un cliente no quiere que el usuario proporcione credenciales en cada sesión, entonces el cliente debe almacenar la contraseña del usuario para que pueda proporcionarla la próxima vez. Este es un inconveniente importante para usar la autenticación básica a menos que el cliente sea solo una aplicación web, en cuyo caso, las cookies pueden abordar algunas de estas preocupaciones. Con aplicaciones nativas, eso generalmente no es una opción.

Hay otro aspecto de OAuth2 que está relacionado con cómo se emiten los tokens y cómo funcionan. Cuando un usuario proporciona credenciales al servidor de autorización (incluso en ROPC), el servidor de autorización puede proporcionar uno o más de los dos tipos de tokens: 1) token de acceso y 2) token de actualización.

Los tokens de acceso se envían al servidor de recursos que otorgará acceso a los recursos después de validarlo, y generalmente tienen una vida útil corta, por ejemplo, 1 hora. El cliente envía tokens de actualización al servidor de autorización para obtener otro token de acceso cuando caduca y, por lo general, tiene una larga vida útil (por ejemplo, de unos días a meses o incluso años).

Cuando el cliente proporciona el token de acceso al servidor de recursos, mira el token y, después de validarlo, mira dentro del token para determinar si permite el acceso o no. Mientras el token de acceso sea válido, el cliente puede seguir usándolo. Digamos que el usuario cierra la aplicación y la inicia al día siguiente, y el token de acceso ha caducado. Ahora el cliente realizará una llamada al servidor de autorización y presentará el token de actualización suponiendo que no ha caducado. El servidor de autorización, dado que ya emitió el token, lo verifica y puede determinar que el usuario no necesita proporcionar las credenciales nuevamente y, por lo tanto, le da otro token de acceso al cliente. El cliente ahora tiene acceso al servidor de recursos nuevamente. Así es como típicamente las aplicaciones cliente para Facebook y Twitter solicitan credenciales una vez y luego no requieren que el usuario proporcione las credenciales nuevamente. Estas aplicaciones nunca necesitan conocer las credenciales de los usuarios y, sin embargo, pueden acceder a los recursos cada vez que el usuario inicia la aplicación.

Ahora el usuario puede ingresar al servidor de autorización (por ejemplo, en su perfil de usuario de Facebook), cambiar la contraseña sin afectar las aplicaciones de ningún cliente. Todos continuarán funcionando correctamente. Si el usuario pierde un dispositivo en el que ya tenía una aplicación con tokens de actualización, puede decirle al servidor de autorización (por ejemplo, Facebook) que "cierre la sesión" de esas aplicaciones que el servidor de autorización (es decir, Facebook) logrará al no respetar ninguna actualizar tokens y obligar al usuario a proporcionar credenciales nuevamente cuando intentan acceder a los recursos a través de esas aplicaciones.

JWT es simplemente el formato de token que generalmente se usa con OAuth2 y OpenID Connect. Los métodos para firmar el token y validarlo también están estandarizados con bibliotecas disponibles para aquellos en lugar de que cada servidor de recursos implemente una solución más. Por lo tanto, la ventaja radica en la reutilización del código que ha sido examinado y sigue siendo compatible.

Implicaciones de seguridad

La autenticación básica será más débil cuando alguno de los escenarios anteriores esté en la imagen. También hay un extenso modelo de amenaza para OAuth2 disponible para desarrolladores que pueden usar las sugerencias para evitar vulnerabilidades comunes en sus implementaciones. Si sigue el modelo de amenaza, verá que muchas vulnerabilidades relacionadas con la implementación (como el redirector abierto y CSRF) también están cubiertas en él. No pasé por la comparación de aquellos contra la autenticación básica en esta respuesta.

La última gran ventaja de OAuth2 es que el protocolo está estandarizado y múltiples servidores de autorización, clientes y servidores de recursos lo cumplen. Numerosas bibliotecas están disponibles para los desarrolladores, que se mantienen de modo que a medida que se encuentran problemas de seguridad en las implementaciones, las bibliotecas se actualizan al tiempo que permiten la interoperabilidad.

Conclusión

Si está escribiendo una nueva aplicación, IMO, el caso ideal sería evitar tanto la autenticación básica como la ROPC debido a los problemas inherentes a ellas. Sin embargo, cada aplicación tiene diferentes necesidades, plazos, competencia del desarrollador, etc., por lo que la decisión es caso por caso. Pero incluso si no tuviera más necesidad que la autenticación básica, al elegirla, podría encerrarse en una arquitectura que puede no ser fácil de ampliar (por ejemplo, si tiene varios servidores en el futuro, no necesariamente querría tener el usuario proporciona credenciales a cada uno de ellos, en lugar de simplemente proporcionar una vez al servidor de autorización, que puede entregar tokens, etc.)

Tenga en cuenta que no abordé su comentario sobre cómo se envían las credenciales a través del cable porque se pueden proteger mediante TLS o un protocolo similar, o una prueba de posesión, etc. Como alguien ya sugirió, la codificación de base 64 es 0 seguridad, por favor no ser engañado por eso. Las diferencias mencionadas anteriormente generalmente están en el nivel arquitectónico y, por lo tanto, ahí es donde me enfoqué porque la arquitectura es la más difícil de cambiar una vez implementada.

Azure Active Directory B2C Basic , un servicio en el que trabajo y que se lanzó recientemente para la vista previa pública, permite que una aplicación de terceros use AAD como servidor de autorización con interoperabilidad con IDP sociales (como Facebook, Google, etc.). También permite a los usuarios crear sus propias cuentas en lugar de usar IDP sociales y que luego se pueden usar con fines de autenticación. También hay otros servicios similares (por ejemplo, otro que conozco es auth0) que pueden usar los desarrolladores para externalizar completamente la autenticación y la gestión de usuarios para sus aplicaciones y recursos. Los desarrolladores utilizan las mismas características de protocolos que mencioné anteriormente para desacoplar el servidor de autorización (AAD), un recurso (por ejemplo, sus API REST), el cliente (por ejemplo, sus aplicaciones móviles) y los usuarios. Espero que esta explicación ayude un poco.


Gracias por un gran ángulo, pero no creo que estas ventajas (a) letting the user agent hold just the token instead of the password, (b) allowing a password change without disrupting existing client apps, (c) allowing users log out other sessionssean específicas de los flujos de autenticación de tokens. Ni las autenticaciones básicas ni las de token mencionan las funciones (b) y (c) en sus especificaciones. Implementar (b) y (c) parece posible para cualquier tipo de autenticación. Implicaría hacer un seguimiento de las contraseñas (preferiblemente sus hashes). La ventaja (a) parece depender del alcance más amplio de la contraseña.
anguila ghEEz

¿Cómo podríamos usar OAuth si el usuario (propietario del recurso) no tiene credenciales con un servidor de autorización externo, pero tiene credenciales en la aplicación del cliente? Es decir, tenemos el propietario del recurso (usuario), el cliente (que representa al usuario y que también contiene credenciales para el usuario) y el servidor de recursos. ¿Cómo puede un servidor de recursos autenticar y autorizar al usuario?
Arun Avanathan

3

Creo que está mal informado sobre el cifrado en torno a las variables GET en una URL

Las únicas personas que pueden ver las variables GET en una solicitud son la computadora original y el servidor receptor ( enlace ).

Solo la búsqueda de DNS basada en el dominio al que se envía la solicitud HTTPS no está cifrada. Todo lo demás, los puertos, las variables GET, la ID del recurso, están encriptados.

La única advertencia es que el servidor receptor puede cerrar sesión en la ruta de solicitud completa, pero usted tiene el control de eso para que pueda proteger esos datos como mejor le parezca.


3

La autenticación básica no es una buena manera de asegurar su API REST. Expliqué las razones por las cuales en esta respuesta .

Cuando crea una API REST, está implementando el servidor de recursos en términos OAuth2. Todo lo que su API debe hacer es validar que el token se haya pasado junto con la solicitud en el encabezado HTTP de autorización sea ​​válido y de un emisor de confianza. Consulte este enlace para ver los pasos para implementar la validación si no hay una biblioteca disponible.

Cómo su cliente adquiere el token del servidor de autorización depende de qué tipo de cliente sea. Recuerde, debe especificar el tipo de cliente que va a utilizar cuando registre el cliente en el servidor de autorización.

En caso de que una aplicación web hable con su servidor, podría usar el código de autorización otorgado . Si se trata de un cliente no confiable, como una aplicación móvil o una aplicación JavaScript, debe usar la concesión implícita .

Para los servicios de back-end que no pueden interactuar con el propietario de un recurso, puede usar la concesión de credenciales del cliente . Para las herramientas de línea de comandos, puede usar las credenciales del cliente o concesión de contraseña del propietario recurso .

Todo depende de qué tipo de cliente esté utilizando.

Finalmente, la validación de un token JWT ocurre en el servidor de recursos sin la necesidad de hablar con el servidor de autorización. Esto conduce a una mejor arquitectura escalable que soluciones que necesitan buscar datos privados para cada cliente.


1

Es seguro o no seguro. Ni mas ni menos. Tener base64 no hace que la autenticación básica (ni nada) sea más segura.

No hay nada de malo en enviar algo sin encriptar si se usa una tubería encriptada como Https.

OAuth tiene más funciones, úsela si la necesita. Para cualquier otra cosa, por ejemplo, la banca, el uso de desafío-respuesta básico está bien y es seguro.


0

Creo que primero debes entender las terminologías. Estás comparando: autorización y firma digital

OAuth es un estándar abierto para la Autorización , donde lo que Amazon está haciendo (según el artículo y los detalles proporcionados en su pregunta) es crear una firma digital válida que le da al destinatario (aquí Amazon) razones para creer que el mensaje fue creado por un conocido remitente, que el remitente no puede negar haber enviado el mensaje ( autenticación y no repudio)

Para qué mecanismo de autorización usar, depende más o menos de su caso de uso.

A continuación se muestra lo que se puede encontrar en StackOverflow aquí :

Autenticación básica que requiere un hashing muy simple para calcular el encabezado único requerido: OAuth es sin duda una autenticación más costosa. Lo importante es darse cuenta de que los dos mecanismos de autenticación tienen propósitos completamente diferentes. La autenticación básica es para autenticar un cliente en una aplicación primaria. OAuth es para autorizar a un tercero a acceder a los datos del cliente desde una aplicación principal. Ambos tienen su lugar y la selección de uno sobre el otro debe ser impulsada por el caso de uso particular de la implementación.

Y aquí hay otro artículo interesante que compara los dos.

La autenticación básica sobre SSL es en realidad bastante responsable, desde un punto de vista de seguridad simplista. Cuando nos enfrentamos con nombres de usuario y contraseñas, la autenticación básica es una solución frecuente, ya que es muy fácil de implementar. La transmisión de credenciales se cifra mediante SSL, y el uso del encabezado "Autorización" es omnipresente en los clientes y sistemas HTTP.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.