CouchDb чтение аутентификации с использованием списков

Я смотрю на портирование веб-сайта в CouchDB, и это выглядит очень интересно.

Однако большая проблема заключается в том, что CouchDB не поддерживает аутентификацию чтения; все документы в базе данных доступны всем читателям.

в другом месте предлагается использовать разные базы данных для разных групп читателей или внедрить аутентификацию читателей на другом (среднем) уровне, ни один из которых не является вариантом для этого проекта, где доступ определяется сложным для каждого документа списки контроля доступа.

Я думал реализовать аутентификацию в списках и ограничить весь доступ к CouchDb этими списками. Это ограничение может быть применено с помощью простых предложений mod_rewrite в Apache, используемых в качестве обратного прокси-сервера. Списки просто извлекают строку и проверяют userCtx по ACL документа. Что-то вроде:

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"});
}

Поскольку у меня нет опыта работы с CouchDB, и я нигде не читал об этом подходе, я хотел бы знать, может ли этот подход работать.

Это способ реализовать доступ на чтение или я злоупотребляю списками для неправильной цели? Не стоит ли ожидать, что такое простое решение возможно с CouchDB?

Ответ 1

Apache mod_rewrite - это средний уровень, поэтому неясно, что вы имеете в виду, когда говорите, что средний уровень не подходит.

Реализация вашей политики безопасности на основе данных в couchdb - это прекрасно. Однако цена заключается в том, что вы несете ответственность за правильность реализации. Это не так плохо, как кажется. Помните, что люди давно занимались этим с веб-приложениями MySQL.

Следует иметь в виду, что CouchDB не поддерживает разрешения на чтение на уровне документа, потому что нецелесообразно отслеживать эти разрешения, поскольку данные переплетаются на всех картах и сокращают количество просмотров. Например, скажем, у нас есть система торгов.

  • Есть два предложения, мое и ваше
  • У меня есть доступ на чтение к моей ставке, которая составляет 10 долларов США, но я не могу прочитать ваш документ по ставке из-за политики промежуточного программного обеспечения
  • Однако я обнаружил представление, которое вычисляет среднее значение всех ставок. Средняя стоимость составляет 7,50 долларов. Поэтому я знаю, что вы предложили 5 долларов, и я понизлю ставку до 6 долларов.

Другими словами, если вы переносите CouchDB API, вам, по крайней мере, потребуется внести в белый список те запросы, которые разрешены. И помните, правила vhost и rewrite выполняются внутри CouchDB, поэтому простого просмотра входящего запроса может быть недостаточно.

Надеюсь, это проливает некоторый свет на то, почему контроль чтения находится на уровне базы данных.

Ответ 2

Обычно достаточно ограничить доступ к определенным представлениям - это можно сделать с помощью списков, как вы предложили (спасибо за идею). Используя неопознанные идентификаторы для документов, у вас уже есть какой-то контроль доступа к документам. Я бы не стал перебирать строки и проверять наличие там разрешений, но я тоже не думаю, что это большая проблема.

Некоторые упоминали здесь, что целью списков является изменение формата - я не согласен, так как даже в официальном руководстве CouchDB говорится, что списки могут даже создавать документы json.

Другой способ - ограничить количество пользователей для каждой базы данных и использовать выборочную репликацию, чтобы одна база данных содержала только те данные, к которым имеет доступ определенная группа пользователей. См. аутентификацию на чтение couchdb. Это на самом деле не для каждого пользователя, но, возможно, в любом случае вариант для вас. Подробнее о отфильтрованной репликации см. http://wiki.apache.org/couchdb/Replication

Изменить: я только что предложил отличную идею для обеспечения прав пользователей для каждого документа в списках с большей производительностью:

  1. Вы передаете имя пользователя в качестве аргумента представлению и соответственно фильтруете.
  2. В списке, используя представление, вы проверяете, совпадает ли имя пользователя с указанным аргументом от фактического пользователя.

Преимущество в том, что CouchDB, насколько мне известно, внутренне использует кэширование для представлений. Я не уверен, как кеширование работает со списками. Также я думаю, что итерация и фильтрация в представлениях обычно быстрее, чем в списках.

Ответ 3

Функции списка - это разумный способ принудительного чтения ACL в простых случаях, но у этого подхода есть несколько недостатков.

Во-первых, вам нужно что-то перед CouchDB, чтобы заблокировать любой запрос на чтение, который не передает через список fn, реализующий ACL. _all-docs, запросы с reduce=true, прямые GETs документов - все и многие другие должны быть заблокированы. Самый простой способ - использовать маски Apache и regexp.

Во-вторых,, вы должны понимать, что вы не можете простым способом контролировать доступ к вложениям. Хотя вы можете заблокировать любой запрос на чтение, который не соответствует вашему шаблону /db/_design/ddoc/_list/list/view, вы не можете создать эффективную пару view + list для обеспечения контроля доступа к вложениям.

Это абсолютно невозможно для CouchDB 1.5 и более ранних версий - индекс представления не может включать данные вложений. Это почти невозможно в CouchDB 1.6, поскольку обработка вложений в кодировке base64, поскольку JSON - это нагрузка на ЦП и ОЗУ.

В-третьих,, в любом случае, этот метод является sloooooow. Причина проста - функции списка не являются потоками. Это означает, что сначала весь запрос представления fn захватывается и сериализуется, затем процессор списков снова десериализует его, а затем результат обрабатывается с использованием функции списка. А потом снова сериализуется.

Ответ 4

Я не уверен, что использование списка - лучший вариант для ограничения доступа к ресурсам, так как список - это функции, которые используются для визуализации представления в определенном формате (RSS, CSV, файлы конфигурации, HTML,...).

Рассматривали ли вы использование документа, содержащего пользователей и их разрешения? Я нашел пост Кореи Нордманн, в котором объясняется, как преобразовать классические пользователя/группы/разрешения из реляционных баз данных в модель CouchDB:

alt text

В зависимости от своих прав пользователь может иметь доступ только к набору определенных представлений.

CouchDB предлагает функции проверки, но они вызываются только при создании или обновлении документа. В книге OReilly говорится, что "система аутентификации является подключаемой, поэтому вы можете интегрироваться с существующими сервисами для аутентификации пользователей в CouchDB с использованием уровня http, интеграции LDAP или с помощью других средств". Но поскольку вы упомянули средний уровень, это не вариант, список может быть временным решением, пока в CouchDB не будет добавлена дополнительная поддержка аутентификации.