2010-08-20 19 views
10

Estoy buscando portar un sitio web en CouchDB y me parece muy interesante.CouchDb read authentication using lists

Sin embargo, un gran problema es que CouchDB no parece ser compatible con la autenticación de lectura; todos los documentos dentro de una base de datos son accesibles por todos los lectores.

Se sugiere elsewhere utilizar diferentes bases de datos para diferentes grupos de lectores o implementar la autenticación del lector en otro nivel intermedio, ninguna de las cuales es una opción para este proyecto donde el acceso está determinado por ACL complejas por documento.

Estaba pensando en implementar la autenticación en las listas y restringir todo el acceso al CouchDb a estas listas. Esta restricción podría ser impuesta por las simples cláusulas mod_rewrite en Apache usadas como proxy inverso. Las listas simplemente buscarán la fila y verificarán el UserCtx contra la ACL del documento. Algo así como:

function(head, req) { 
    var row; 
    while (row = getRow()) { 
    if (row.value.ACL[req.userCtx.name]) 
     send(row.value); 
    else 
     throw({unauthorized : "You are not allowed to access this resource"}); 
} 

Como no tengo experiencia con CouchDB, y no he leído acerca de este enfoque en cualquier lugar, me gustaría saber si este enfoque podría funcionar.

¿Es esta una forma de implementar el acceso de lectura o estoy abusando de las listas para el propósito equivocado? ¿No debería esperar que una solución tan simple sea posible con CouchDB?

+1

Eche un vistazo a https://github.com/ermouth/covercouch - Implementa ACL de lectura manteniendo intacta la API de REST CouchDB original. – ermouth

Respuesta

1

No estoy seguro de que el uso de la lista sea la mejor opción para restringir el acceso a los recursos ya que la lista son funciones que se utilizan para renderizar una vista en formato específico (RSS, CSV, archivos de configuración, HTML, ... .).

¿Ha considerado utilizar un documento que contenga usuarios y sus permisos? Me encontrado a post by Kore Nordmann que explica cómo convertir los clásicos de usuario/grupo/permisos de bases de datos relacionales para el modelo CouchDB:

alt text

En función de sus permisos, un usuario tendría acceso a sólo un conjunto de puntos de vista definidos.

CouchDB ofrece funciones de validación, pero solo se llaman cuando se crea o actualiza un documento. El O’Reilly book establece que "El sistema de autenticación es conectable, por lo que puede integrarse con los servicios existentes para autenticar a los usuarios a CouchDB utilizando una capa http, integración LDAP, o por otros medios". Pero como mencionó que un nivel intermedio no es una opción, la lista podría ser una solución temporal hasta que se agregue más soporte de autenticación a CouchDB.

+0

Gracias. La publicación de Kore Nordmann utiliza tablas de usuario/permiso como ejemplo de datos y cómo se transforma en CouchDB. No parece abordar el problema de restringir realmente el acceso a los recursos. – Tomas

+0

Además, entiendo que el propósito de las listas es principalmente cambiar el formato, entiendo que también se usan para filtrar más allá del árbol B, ¿verdad? – Tomas

+0

Tiene razón cuando la publicación no ofrece una solución completa al problema de permisos, pero es un buen punto de partida y, como se muestra en la imagen, puede usar la estructura de "permisos" para mantener las vistas disponibles para un usuario en particular. No sabía acerca de la relación lista/árbol B, pero la estoy buscando ahora mismo. ¿Tienes algún enlace que lo explique con más detalle? http://books.couchdb.org/relax/appendix/btrees explica cómo se implementa B-Trees (básicamente). – jdecuyper

5

Apache mod_rewrite es un nivel medio, por lo que no está claro a qué se refiere cuando dice que un nivel medio no es una opción.

La implementación de su política de seguridad basada en datos en couchdb está perfectamente bien. Sin embargo, el costo es que usted es responsable de que la implementación sea correcta. No es tan malo como parece. Recuerde, la gente ha estado haciendo esto con las aplicaciones web MySQL durante mucho tiempo.

Lo que hay que tener en cuenta es que CouchDB no admite permisos de lectura a nivel de documento porque no es práctico rastrear esos permisos a medida que los datos se entrelazan en todos los mapas y se reducen las vistas. Por ejemplo, supongamos que tenemos un sistema de ofertas.

  • Hay dos ofertas, la mía y la tuya
  • que tengan acceso de lectura a mi oferta que es de $ 10, pero no puedo leer su documento de oferta debido a la política de middleware
  • Sin embargo, me descubre una vista que calcula la promedio de todas las ofertas. El promedio es $ 7.50. Por lo tanto, sé que hace una oferta de $ 5 y voy a bajar mi oferta a $ 6

En otras palabras, si usted está envolviendo la API CouchDB, se al menos necesita a la lista blanca aquellas consultas que están autorizados. Y recuerde, las reglas de vhost y reescritura se ejecutan dentro de CouchDB, por lo que simplemente mirar la consulta entrante puede no ser suficiente.

Esperemos que arroje algo de luz sobre por qué el control de lectura es a nivel de base de datos.

+0

Gracias. ¿A qué te refieres con "reglas de vhost y reescritura que se ejecutan dentro de CouchDB"? – Tomas

+0

¿Podría (o alguien) abordar más específicamente si las LISTAS son una buena forma de implementar esto? – Tomas

+1

Hola, Tomás. Respuesta corta: ** no **. En general, las listas no son una buena forma de aplicar la política de seguridad porque el usuario simplemente puede consultar/_all_docs y ver toda la base de datos. – JasonSmith

4

Por lo general, es suficiente restringir el acceso a ciertas vistas, esto se puede hacer a través de listas como las que propuso (gracias por la idea). Al usar identificadores indescifrables para documentos, ya tiene algún tipo de control de acceso para los documentos. Evitaría recorrer las filas y verificar los permisos allí, pero tampoco creo que sea un gran problema.

Algunos han mencionado aquí que el propósito de las listas es cambiar el formato - No estoy de acuerdo, ya que incluso la guía oficial de CouchDB establece que las listas podrían incluso producir documentos json.

Otra forma es restringir usuarios por base de datos y usar la replicación selectiva para que una base de datos solo contenga los datos a los que un determinado grupo de usuarios tiene acceso. Consulte couchdb read authentication Esto no es realmente por usuario, pero tal vez de todos modos sea una opción para usted. Para más detalles sobre la replicación filtrada ver http://wiki.apache.org/couchdb/Replication

Editar: Sólo ocurrió una gran idea para hacer cumplir por los permisos de usuario de documentos a través de listas con un mejor rendimiento:

  1. se pasa el nombre de usuario como argumento para la vista y filtro en consecuencia.
  2. En la lista que utiliza la vista, verifica si el nombre de usuario del argumento dado es idéntico al usuario real.

La ventaja es que CouchDB, por lo que sé, internamente utiliza el almacenamiento en caché para las vistas. No estoy seguro de cómo funciona el almacenamiento en caché con listas. También creo que iterar y filtrar en vistas es generalmente más rápido que en listas.

+0

Gracias por su respuesta. Acerca de su idea editada, esto parece ser útil solo en el caso limitado en el que no se requiere ordenar o filtrar otro nombre que no sea el nombre de usuario como, ¿correcto? – Tomas

+0

No, puede usarlo como desee, porque CouchDB permite ordenar con múltiples valores. Simplemente haga algo como "emitir ([doc.user_id, doc.sort_value], doc)". –

+2

Buena respuesta. ¡Pero recuerde, el usuario podría buscar/_all_docs y ver toda la base de datos! Si tiene una capa de proxy y está * seguro * de que bloquea todas las URL innecesarias, entonces una lista podría funcionar. Pero eso es sutil. Las reescrituras, las funciones de mostrar/enumerar y las vistas podrían potencialmente abrir una puerta trasera a los datos. – JasonSmith

2

Las funciones de lista son una forma razonable de exigir la lectura de ACL en casos simples, pero este enfoque tiene varios inconvenientes.

Primero,, necesita algo delante de CouchDB para bloquear cualquier solicitud de lectura, que no se canaliza a través de la lista fn que implementa ACL. _all-docs, solicitudes con reduce=true, GET directos de documentos: todo y muchos otros deben estar bloqueados. La forma más sencilla es utilizar máscaras Apache y regexp.

En segundo lugar,, debe comprender que no se puede controlar de forma sencilla el acceso a los archivos adjuntos. Aunque puede bloquear cualquier solicitud de lectura, que no coincide con su patrón /db/_design/ddoc/_list/list/view, no puede construir un par de vista + lista efectiva para proporcionar control de acceso a los archivos adjuntos.

Es absolutamente imposible para CouchDB 1.5 y versiones anteriores - ver índice no puede incluir datos adjuntos. Es casi imposible en CouchDB 1.6 ya que el procesamiento de codificación base64 se conecta como JSON es CPU y RAM hog.

Tercero, de cualquier manera, este método es sloooooow. La razón es simple: las funciones de lista no son transmisiones. Significa la primera respuesta de la vista fn es capturada y serializada, luego el procesador de lista lo deserializa de nuevo, y luego el resultado se procesa usando la función de lista. Y luego, nuevamente serializado.