Pregunta Autenticación RESTful


¿Qué significa la Autenticación RESTful y cómo funciona? No puedo encontrar una buena descripción en Google. Mi único entendimiento es que pasas la clave de sesión (remeberal) en la URL, pero esto podría ser terriblemente incorrecto.


664
2017-11-26 01:47


origen


Respuestas:


Cómo manejar la autenticación en una arquitectura RESTful Cliente-Servidor es una cuestión de debate.

Comúnmente, se puede lograr, en el mundo SOA sobre HTTP a través de:

  • Autorización básica de HTTP sobre HTTPS;
  • Cookies y gestión de sesiones;
  • Token en encabezados HTTP (p. OAuth 2.0);
  • Autenticación de consulta con parámetros de firma adicionales.

Tendrá que adaptar, o incluso mejor, mezclar esas técnicas, para que coincida con la arquitectura de su software en el mejor de los casos.

Cada esquema de autenticación tiene sus propias PRO y CONs, según el propósito de su política de seguridad y arquitectura de software.

Autorización básica de HTTP sobre HTTPS

Esta primera solución, basada en el protocolo HTTPS estándar, es utilizada por la mayoría de los servicios web.

GET /spec.html HTTP/1.1
Host: www.example.org
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Es fácil de implementar, está disponible de forma predeterminada en todos los navegadores, pero tiene algunos inconvenientes conocidos, como la espantosa ventana de autenticación que se muestra en el navegador, que persistirá (no hay una característica similar a LogOut), alguna CPU adicional del lado del servidor consumo, y el hecho de que el nombre de usuario y la contraseña se transmiten (a través de HTTPS) al Servidor (debe ser más seguro dejar la contraseña solo en el lado del cliente, durante la entrada del teclado, y almacenarse como hash seguro en el Servidor).

Podemos usar Autenticación resumida, pero también requiere HTTPS, ya que es vulnerable a MiM o Repetición ataques, y es específico de HTTP.

Sesión a través de cookies

Para ser sincero, una sesión administrada en el servidor no es verdaderamente apátrida.

Una posibilidad podría ser mantener todos los datos dentro del contenido de la cookie. Y, por diseño, la cookie se maneja en el lado del servidor (de hecho, el cliente ni siquiera intenta interpretar esta información de cookies: simplemente la devuelve al servidor en cada solicitud sucesiva). Pero estos datos de cookies son datos de estado de la aplicación, por lo que el cliente debe administrarlo, no el servidor, en un mundo sin estado puro.

GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: theme=light; sessionToken=abc123

La técnica de cookies en sí misma está vinculada a HTTP, por lo que no es realmente RESTful, que debería ser independiente del protocolo, en mi humilde opinión. Es vulnerable a MiM o Repetición ataques.

Otorgado mediante Token (OAuth2)

Una alternativa es colocar un token dentro de los encabezados HTTP para que la solicitud se autentique. Esto es lo que OAuth 2.0 lo hace, por ejemplo. Ver el RFC 6749:

 GET /resource/1 HTTP/1.1
 Host: example.com
 Authorization: Bearer mF_9.B5f-4.1JqM

En resumen, esto es muy similar a una cookie, y sufre los mismos problemas: no apátrida, dependiendo de los detalles de la transmisión HTTP, y sujeto a una gran cantidad de debilidades de seguridad - incluyendo MiM y Replay - por lo que se debe usar solo a través de HTTPS.

Autenticación de consultas

La Autenticación de consultas consiste en firmar cada solicitud RESTful a través de algunos parámetros adicionales en el URI. Ver este artículo de referencia.

Fue definido como tal en este artículo:

Todas las consultas REST se deben autenticar mediante la firma de los parámetros de consulta   ordenados en minúsculas, orden alfabético usando la credencial privada   como el token de firma. La firma debe ocurrir antes de que la URL codifique el   cadena de consulta.

Esta técnica es quizás la más compatible con una arquitectura sin estado, y también se puede implementar con una gestión de sesión ligera (usando sesiones en memoria en lugar de persistencia de DB).

Por ejemplo, aquí hay una muestra genérica de URI del enlace de arriba:

GET /object?apiKey=Qwerty2010

debe transmitirse como tal:

GET /object?timestamp=1261496500&apiKey=Qwerty2010&signature=abcdef0123456789

La cadena que se está firmando es /object?apikey=Qwerty2010&timestamp=1261496500 y la firma es el hash SHA256 de esa cadena que usa el componente privado de la clave API.

El almacenamiento en caché de datos del lado del servidor siempre puede estar disponible. Por ejemplo, en nuestro marco, almacenamos en caché las respuestas en el nivel SQL, no en el nivel URI. Por lo tanto, agregar este parámetro adicional no rompe el mecanismo de caché.

Ver Este artículo para obtener algunos detalles sobre la autenticación RESTful en nuestro marco cliente / servidor ORM / SOA / MVC, basado en JSON y REST. Dado que permitimos la comunicación no solo a través de HTTP / 1.1, sino también canalizaciones con nombre o mensajes GDI (localmente), intentamos implementar un patrón de autenticación verdaderamente RESTful y no confiar en la especificidad de HTTP (como el encabezado o las cookies).

En la práctica, el próximo Autenticación de tokens MAC para OAuth 2.0 puede ser una gran mejora con respecto al esquema actual "Concedido por Token". Pero esto todavía es un trabajo en progreso y está vinculado a la transmisión HTTP.

Conclusión

Vale la pena concluir que REST no solo está basado en HTTP, incluso si, en la práctica, se implementa principalmente a través de HTTP. REST puede usar otras capas de comunicación. Por lo tanto, una autenticación RESTful no es solo un sinónimo de autenticación HTTP, independientemente de las respuestas de Google. Incluso no debería usar el mecanismo HTTP en absoluto, sino que debe abstraerse de la capa de comunicación.


522
2017-08-23 09:29



Dudo que la gente que gritó con entusiasmo "Autenticación HTTP" alguna vez intentó hacer una aplicación basada en navegador (en lugar de un servicio web de máquina a máquina) con REST (sin intención de ofender, simplemente no creo que alguna vez hayan enfrentado las complicaciones) .

Los problemas que encontré con el uso de Autenticación HTTP en los servicios RESTful que producen páginas HTML para ser vistos en un navegador son:

  • el usuario generalmente recibe un feo cuadro de inicio de sesión hecho por el navegador, que es muy poco amigable para el usuario. no puede agregar recuperación de contraseña, cuadros de ayuda, etcétera.
  • cerrar la sesión o iniciar sesión con un nombre diferente es un problema: los navegadores seguirán enviando información de autenticación al sitio hasta que cierre la ventana
  • los tiempos de espera son difíciles

Un artículo muy perspicaz que aborda estos punto por punto es aquí, pero esto da como resultado un mucho de hackeo de JavaScript específico del navegador, soluciones para soluciones temporales, etcétera. Como tal, tampoco es compatible con versiones anteriores, por lo que requerirá mantenimiento constante a medida que se lanzan nuevos navegadores. No considero ese diseño limpio y claro, además siento que es mucho trabajo extra y dolor de cabeza solo para poder mostrar con entusiasmo mi insignia REST a mis amigos.

Creo que las cookies son la solución. Pero espera, las galletas son malas, ¿verdad? No, no lo son, la forma en que se utilizan a menudo las cookies es malvada. Una cookie en sí misma es solo una parte de la información del lado del cliente, al igual que la información de autenticación HTTP de la que el navegador realizaría un seguimiento mientras navegas. Y esta información del lado del cliente se envía al servidor cada vez que se solicita, igual que la información de autenticación HTTP. Conceptualmente, la única diferencia es que el contenido de este pedazo de estado del lado del cliente puede ser determinado por el servidor como parte de su respuesta.

Haciendo de las sesiones un recurso RESTful con solo las siguientes reglas:

  • UN sesión asigna una clave a una identificación de usuario (y posiblemente una marca de tiempo de última acción para tiempos de espera)
  • Si un sesión existe, entonces eso significa que la clave es válida.
  • El inicio de sesión significa POSTING en / sessions, una nueva clave se configura como una cookie
  • Cerrar sesión significa DELETEing / sessions / {key} (con POST sobrecargado, recuerde, somos un navegador, y HTML 5 está aún por recorrer)
  • La autenticación se realiza enviando la clave como una cookie en cada solicitud y verificando si la sesión existe y es válida.

La única diferencia con la Autenticación HTTP es que el servidor genera la clave de autenticación y la envía al cliente que la sigue enviando, en lugar de que el cliente la compute a partir de las credenciales ingresadas.

converter42 agrega que al usar https (que deberíamos), es importante que la cookie tenga su bandera segura establecida para que la información de autenticación nunca se envíe a través de una conexión no segura. Gran punto, no lo había visto yo mismo.

Siento que esta es una solución suficiente que funciona bien, pero debo admitir que no soy lo suficientemente experto en seguridad para identificar agujeros potenciales en este esquema; todo lo que sé es que cientos de aplicaciones web no RESTful usan esencialmente lo mismo protocolo de inicio de sesión ($ _SESSION inphp, HttpSession en Java EE, etc.). El contenido del encabezado de la cookie se usa simplemente para direccionar un recurso del lado del servidor, al igual que un idioma de aceptación podría usarse para acceder a los recursos de traducción, etcétera. Siento que es lo mismo, ¿pero quizás otros no? ¿Qué piensan chicos?


403
2017-07-16 07:39



Bastante ya se dice sobre este tema aquí. Pero aquí está mi 2 centavos.

Hay 2 modos de interacción:

  1. humano a máquina (HTM)
  2. máquina a máquina (MTM)

La máquina es el denominador común, expresado como las API REST, y los actores / clientes son los humanos o las máquinas.

Ahora, en una arquitectura verdaderamente RESTful, el concepto de apatridia implica que todos los estados de aplicación relevantes (es decir, los estados del lado del cliente) se deben suministrar con todas y cada una de las solicitudes. Por relevante, se entiende que lo que requiera la API REST para procesar la solicitud y enviar una respuesta adecuada.

Cuando consideramos esto en el contexto de las aplicaciones de humano a máquina, "basadas en navegador" como señala Skrebbel más arriba, esto significa que la aplicación (web) que se ejecuta en el navegador deberá enviar su estado e información relevante con cada solicitud hace a la parte trasera API REST.

Considere esto: tiene una plataforma de datos / información expuesta como un conjunto de API REST. Quizás tenga una plataforma de BI de autoservicio que maneje todos los cubos de datos. Pero desea que sus clientes (humanos) accedan a esto a través de (1) la aplicación web, (2) la aplicación móvil y (3) alguna aplicación de terceros. Al final, incluso la cadena de MTM conduce a HTM, a la derecha. Entonces los usuarios humanos permanecen en el vértice de la cadena de información.

En los primeros 2 casos, tiene un caso de interacción de persona a máquina, la información que realmente consume un usuario humano. En el último caso, tiene un programa de máquina que consume las API REST.

El concepto de autenticación se aplica en todos los ámbitos. ¿Cómo se diseñará esto para que se acceda a sus API REST de manera uniforme y segura? La forma en que veo esto, hay 2 formas:

Way-1:

  1. No hay inicio de sesión para comenzar. Cada solicitud realiza el inicio de sesión
  2. El cliente envía sus parámetros de identificación + la solicitud específica parámetros con cada solicitud
  3. La API REST los toma, da la vuelta, hace ping a la tienda del usuario (sea lo que sea) y confirma la autenticación
  4. Si se establece la autenticación, los servicios de la solicitud; de lo contrario, niega con el código de estado HTTP apropiado
  5. Repita lo anterior para cada solicitud en todas las API REST de su catalogar

Way-2:

  1. El cliente comienza con una solicitud de autenticación
  2. Una API REST de inicio de sesión manejará todas las solicitudes
  3. Toma los parámetros de autenticación (clave de API, uid / pwd o lo que sea que elegir) y verifica la autenticación contra la tienda del usuario (LDAP, AD o MySQL DB, etc.)
  4. Si se verifica, crea un token de autenticación y se lo devuelve al cliente / llamante
  5. A continuación, la persona que llama envía este auth token + request params específicos con cada solicitud posterior a otras API de REST de negocios, hasta que se cierre la sesión o hasta que expire el arrendamiento

Claramente, en Way-2, las API REST necesitarán una forma de reconocer y confiar en el token como válido. La API de inicio de sesión realizó la verificación de autenticación y, por lo tanto, es necesario que otras API de REST de su catálogo confíen en esa "clave de valet".

Esto, por supuesto, significa que la clave / token de autenticación deberá almacenarse y compartirse entre las API REST. Este repositorio compartido y confiable de tokens puede ser local / federado, permitiendo que las API REST de otras organizaciones confíen entre sí.

Pero yo divago.

El punto es que se debe mantener y compartir un "estado" (sobre el estado autenticado del cliente) para que todas las API REST puedan crear un círculo de confianza. Si no hacemos esto, que es el Way-1, debemos aceptar que se debe realizar un acto de autenticación para todas las solicitudes que ingresen.

Realizar la autenticación es un proceso intensivo de recursos. Imagínese la ejecución de consultas SQL, para cada solicitud entrante, contra su tienda de usuario para verificar la coincidencia uid / pwd. O, para encriptar y realizar coincidencias hash (el estilo AWS). Y desde el punto de vista arquitectónico, todas las API REST necesitarán realizar esto, sospecho, utilizando un servicio común de inicio de sesión. Porque, si no lo haces, entonces tiras el código de autenticación en todas partes. Un gran desastre.

Así que más capas, más latencia.

Ahora, tome Way-1 y aplique a HTM. ¿A su usuario (humano) realmente le importa si tiene que enviar uid / pwd / hash o lo que sea con cada pedido? No, siempre y cuando no la molestes lanzando la página de autenticación / inicio de sesión cada segundo. Buena suerte tener clientes si lo hace. Por lo tanto, lo que hará es almacenar la información de inicio de sesión en algún lugar en el lado del cliente, en el navegador, al principio, y enviarla con cada solicitud realizada. Para el usuario (humano), ella ya ha iniciado sesión, y hay una "sesión" disponible. Pero, en realidad, ella está autenticada en cada solicitud.

Lo mismo con Way-2. Su usuario (humano) nunca lo notará. Entonces no hay daño hecho.

¿Qué pasa si aplicamos Way-1 a MTM? En este caso, dado que es una máquina, podemos aburrir muchísimo a este tipo al pedirle que envíe información de autenticación con cada solicitud. ¡A nadie le importa! Realizar Way-2 en MTM no provocará ninguna reacción especial; es una maldita máquina. ¡No podría importarle menos!

Entonces, realmente, la pregunta es qué satisface tu necesidad. Apatridia tiene un precio a pagar. Pague el precio y siga adelante. Si quieres ser un purista, entonces paga el precio por eso y sigue adelante.

Al final, las filosofías no importan. Lo que realmente importa es el descubrimiento de información, la presentación y la experiencia de consumo. Si la gente ama tus API, hiciste tu trabajo.


128
2017-10-14 21:29



Aquí hay una verdadera y completamente RESTful solución de autenticación:

  1. Cree un par de claves públicas / privadas en el servidor de autenticación.
  2. Distribuya la clave pública a todos los servidores.
  3. Cuando un cliente se autentica:

    3.1. emita un token que contenga lo siguiente:

    • Tiempo de expiración
    • nombre de los usuarios (opcional)
    • IP de los usuarios (opcional)
    • hash de una contraseña (opcional)

    3.2. Encripta el token con la clave privada.

    3.3. Envíe el token encriptado nuevamente al usuario.

  4. Cuando el usuario accede a cualquier API, también debe pasar su token de autenticación.

  5. Los servidores pueden verificar que el token sea válido descifrándolo mediante la clave pública del servidor de autenticación.

Esta es la autenticación sin estado / RESTful.

Tenga en cuenta que si se incluyera un hash de contraseña, el usuario también enviaría la contraseña no encriptada junto con el token de autenticación. El servidor podría verificar que la contraseña coincida con la contraseña que se utilizó para crear el token de autenticación mediante la comparación de hashes. Una conexión segura usando algo como HTTPS sería necesaria. Javascript en el lado del cliente podría manejar la contraseña del usuario y almacenarla en el lado del cliente, ya sea en la memoria o en una cookie, posiblemente encriptada con el servidor público llave.


46
2017-08-13 20:09



Para ser honesto, he visto excelentes respuestas aquí, pero algo que me molesta un poco es cuando alguien llevará todo el concepto de apátridas a un extremo donde se vuelve dogmático. Me recuerda a esos viejos fanáticos de Smalltalk que solo querían abrazar OO puro y si algo no es un objeto, entonces lo estás haciendo mal. Dáme un respiro.

Se supone que el enfoque RESTful te facilita la vida y reduce los gastos generales y el costo de las sesiones, trata de seguirlo como es una buena idea, pero en el momento en que sigas una disciplina (cualquier disciplina / guía) hasta el extremo donde ya no brinda el beneficio para el que estaba destinado, entonces lo estás haciendo mal. Algunos de los mejores lenguajes de hoy tienen tanto programación funcional como orientación a objetos.

Si la forma más fácil de resolver su problema es almacenar la clave de autenticación en una cookie y enviarla en el encabezado HTTP, entonces hágalo, simplemente no abuse de ella. Recuerde que las sesiones son malas cuando se vuelven pesadas y grandes, si toda la sesión consiste en una cadena corta que contiene una tecla, entonces, ¿cuál es el problema?

Estoy abierto a aceptar correcciones en los comentarios, pero simplemente no veo el sentido (hasta ahora) de hacer que nuestras vidas sean miserables para evitar simplemente tener un gran diccionario de hashes en nuestro servidor.


34
2018-03-26 23:13



En primer lugar, un servicio web RESTful es APÁTRIDA (o en otras palabras, SIN SESSION) Por lo tanto, un servicio RESTful no tiene ni debe tener un concepto de sesión o cookies involucradas. La forma de realizar la autenticación o autorización en el servicio RESTful es mediante el uso del encabezado Autorización HTTP como se define en las especificaciones HTTP RFC 2616. Cada solicitud debe contener el encabezado Autorización HTTP, y la solicitud debe enviarse a través de una conexión HTTP (SSL). Esta es la forma correcta de realizar la autenticación y verificar la autorización de las solicitudes en un servicio web HTTP RESTful. Implementé un servicio web RESTful para la aplicación Cisco PRIME Performance Manager en Cisco Systems. Y como parte de ese servicio web, también implementé autenticación / autorización.

Rubens Gomes.


31
2017-11-26 03:06



Ciertamente no se trata de "claves de sesión", ya que generalmente se utiliza para referirse a la autenticación sin sesión que se realiza dentro de todas las restricciones de REST. Cada solicitud es autodescriptiva, y contiene suficiente información para autorizar la solicitud por sí misma sin ningún estado de aplicación del lado del servidor.

La manera más fácil de abordar esto es comenzando con los mecanismos de autenticación incorporados de HTTP en RFC 2617.


21
2017-10-15 19:35



El artículo "muy perspicaz" mencionado por @skrebel ( http://www.berenddeboer.net/rest/authentication.html ) discute un método de autenticación enrevesado pero realmente roto.

Puede intentar visitar la página (que se supone que solo puede ver el usuario autenticado) http://www.berenddeboer.net/rest/site/authenticated.html sin ninguna credencial de inicio de sesión.

(Lo siento, no puedo comentar sobre la respuesta).

Yo diría que el RESTO y la autenticación simplemente no se mezclan. REST significa sin estado pero 'autentificado' es un estado. No puedes tenerlos a ambos en la misma capa. Si usted es un defensor RESTful y frunce el ceño ante los estados, entonces debe ir con HTTPS (es decir, deje el problema de seguridad en otra capa).


14
2018-01-19 06:45



Creo que la recuperación de la autenticación implica el paso de un token de autenticación como parámetro en la solicitud. Algunos ejemplos son el uso de apikeys por parte de api. No creo que el uso de cookies o http auth califique.


11
2018-01-14 13:30



Creo que el siguiente enfoque se puede utilizar para la autenticación del servicio REST:

  1. Cree una API RESTful de inicio de sesión para aceptar el nombre de usuario y la contraseña para la autenticación. Utilice el método HTTP POST para evitar el almacenamiento en caché y SSL para la seguridad durante el tránsito En la autenticación exitosa, la API devuelve dos JWT: un token de acceso (validez más corta, digamos 30 minutos) y un token de actualización (validez más larga, por ejemplo, 24 horas)
  2. El cliente (una interfaz de usuario basada en web) almacena los JWT en el almacenamiento local y en cada llamada subsiguiente de API pasa el token de acceso en el encabezado "Autorización: token de acceso de portador"
  3. La API verifica la validez del token al verificar la firma y la fecha de caducidad. Si el token es válido, verifique si el usuario (interpreta el reclamo "sub" en JWT como nombre de usuario) tiene acceso a la API con una búsqueda en caché. Si el usuario está autorizado para acceder a la API, ejecute la lógica comercial
  4. Si el token está vencido, la API devuelve el código de respuesta HTTP 400
  5. El cliente, al recibir 400/401, invoca otra API REST con el token de actualización en el encabezado "Autorización: portador # token refresh" para obtener un nuevo token de acceso.
  6. Al recibir la llamada con el token de actualización, verifique si el token de actualización es válido al verificar la firma y la fecha de caducidad. Si el token de actualización es válido, actualice el acceso al caché correcto del usuario desde el DB y devuelva el token de acceso nuevo y el token de actualización. Si el token de actualización no es válido, devuelva el código de respuesta HTTP 400
  7. Si se devuelve un token de acceso y un token de actualización nuevos, vaya al paso 2. Si se devuelve el código de respuesta HTTP 400, el cliente asume que el token de actualización ha caducado y solicita el nombre de usuario y la contraseña del usuario
  8. Para cerrar la sesión, purgue el almacenamiento local

Con este enfoque, estamos realizando la costosa operación de cargar el caché con los detalles de acceso específicos del usuario cada 30 minutos. Por lo tanto, si se revoca un acceso o se otorga un nuevo acceso, demora 30 minutos para reflejar o un cierre de sesión seguido de un inicio de sesión.


7
2017-12-08 22:44