Авторизация CouchDB на основе базы данных - PullRequest
25 голосов
/ 29 октября 2010

Я работаю над приложением, поддерживаемым CouchDB.По сути, я хочу создать базу данных для каждого отдельного пользователя моего приложения.Для этого пользователь с правами администратора создаст базу данных, но в дальнейшем ему нужно будет получить доступ к своей базе данных (используя HTTP-аутентификацию через SSL).У меня было адское время, чтобы понять это.

Лучший ресурс, который я нашел, находится в вики CouchDB по этой ссылке:

http://wiki.apache.org/couchdb/Security_Features_Overview#Authorization

Предполагается, что вы можете установить авторизацию для каждой базы данных, создавдокумент под названием «_security», к которому вы добавляете хэш администраторов и читателей.Когда я пытаюсь создать этот документ, я получаю сообщение «Неверный специальный элемент документа: _security».

$ curl -X GET http://localhost:5984
{"couchdb":"Welcome","version":"1.0.1"}

Любая помощь приветствуется!

Приветствия,

Аарон.

Ответы [ 3 ]

47 голосов
/ 30 октября 2010

Не должно быть проблем с этим подходом.

Допустим, у вас есть тестовая база данных, и у вас уже есть учетная запись администратора:

curl -X PUT http://localhost:5984/test -u "admin:123"

Теперь вы можете создать для него документ _security:

curl -X PUT http://localhost:5984/test/_security -u "admin:123" -d '{"admins":{"names":[], "roles":[]}, "readers":{"names":["joe"],"roles":[]}}'

Их сможет прочитать только пользователь «Джо». Для создания пользователя у вас уже должен быть хэшированный пароль sha1:

curl -X POST http://localhost:5984/_users -d '{"_id":"org.couchdb.user:joe","type":"user","name":"joe","roles":[],"password_sha":"c348c1794df04a0473a11234389e74a236833822", "salt":"1"}' -H "Content-Type: application/json"

Этот пользователь имеет хешированный пароль "123", используя sha1 с солью "1" (sha1 ("123" + "1")), поэтому он может читать базу данных:

curl -X GET http://localhost:5984/test -u "joe:123"

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

ОБНОВЛЕНО: Защита писателя

Вышеуказанный метод вызывает проблему с читателем, но разрешение читателя здесь на самом деле означает «чтение / запись общих документов», поэтому он позволяет записывать документы, кроме design-docs. «Администраторам» в _security doc разрешено писать do design-docs в эту базу данных.

Другой подход, взятый из вашего собственного ответа, - «validate_doc_update», вы можете иметь validate_doc_update, как указано в файле:

function(new_doc, old_doc, userCtx) {
  if(!userCtx || userCtx.name != "joe") {
      throw({forbidden: "Bad user"});
  }
}

И вставьте его в дизайн couchdb:

curl -X PUT http://localhost:5984/test/_design/security -d "{ \"validate_doc_update\": \"function(new_doc,doc,userCtx) { if(userCtx || userCtx.name != 'joe') {throw({forbidden: 'Bad user'})}}\"}" --user 'admin:123'

Им "Джо" может записывать в базу данных с использованием обычной аутентификации:

curl -X PUT http://localhost:5984/test/foobar -d '{"foo":"bar"}' -u 'joe:123'

Как вы уже говорили, вы можете использовать _session api, чтобы получить cookie для аутентификации:

curl http://localhost:5984/_session -v -X POST -d 'name=joe&password=123' -H "Content-Type: application/x-www-form-urlencodeddata"

Это вернет заголовок как:

Set-Cookie: AuthSession=am9lOjRDRDE1NzQ1Oj_xIexerFtLI6EWrBN8IWYWoDRz; Version=1; Path=/; HttpOnly

Таким образом, вы можете включить cookie «AuthSession = am9lOjRDRDE1NzQ1Oj_xIexerFtLI6EWrBN8IWYWoDRz» в ваши следующие запросы, и они будут аутентифицированы.

5 голосов
/ 01 ноября 2010

Я проводил больше исследований и тестирований, и я хочу подвести итог, куда я попал и что еще не работает для меня.

Прежде всего, извинения за тех, кто читает этоВопрос: я искал способы установить разрешения для людей, чтобы писать, а не читать базу данных.Оказывается, будет большая разница: методы создания «читателя» полностью отличаются от создания «писателя» (этого термина на самом деле не существует, хотя мне интересно, почему).

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

curl -X PUT http://admin:password@localhost:5984/_users/org.couchdb.user:username -d '{"type":"user", "hashed_password":"2bf184a2d152aad139dc4facd7710ee848c2af27", "name":"username", "roles":[]}'

Обратите внимание, что вам, очевидно, необходимо указать пространство имен пользователя с префиксом "org.couchdb.user".Я использовал метод хэширования Ruby, чтобы получить значение hashed_password:

require 'digest/sha1'
pass_hash = Digest::SHA1.hexdigest(password)

Это позволяет получить в базу данных, по-видимому, действительного пользователя.Следующим шагом будет назначение этого пользователя в качестве «писателя» (ха, вот он снова!) Для новой базы данных, которую я создал.Поэтому я мог бы сделать что-то вроде:

curl -X PUT http://admin:password@localhost:5984/newdatabase

, а затем

curl -X PUT http://admin:password@localhost:5984/newdatabase/_design/security -d @security.json

Этот файл .json содержит функцию Javascript для ключа validate_doc_update, и эта функция выглядит следующим образом:

function(new_doc, old_doc, userCtx) {
     if(userCtx.name != username) {
         throw({forbidden: "Please log in first."});
     }
   }

Это окольный путь, но это имеет смысл.Однако сейчас я столкнулся с проблемой: очевидно, переменная userCtx не заполняется, пока пользователь не аутентифицируется. В этой статье предполагается, что все, что вам нужно сделать, это передать учетные данные через HTTP-запрос в специальную базу данных _session, например:

curl -X POST http://username:password@localhost:5984/_session

Я могу сделать это для своего администратора,и userCtx var будет заполнен.Но для моего недавно созданного пользователя это не удается:

$ curl http://org.couchdb.user:username:password@localhost:5984/_session
{"ok":true,"userCtx":{"name":null,"roles":[]},"info":{"authentication_db":"_users","authentication_handlers":["cookie","oauth","default"]}}

Обратите внимание, что хэш userCtx равен нулю.Интересно, вызывает ли проблема то пространство имен?В нем есть чертово двоеточие, так что, может быть, есть некоторая путаница с паролем?Я пытался сделать это без пространства имен, и это не работает вообще;по крайней мере, здесь мой запрос, похоже, попал в базу данных и получил ответ.

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

Спасибо!

Аарон.

0 голосов
/ 05 июня 2013

Вы можете проверить Мэтта Вудворда - Полное руководство по аутентификации и безопасности CouchDB http://blog.mattwoodward.com/2012/03/definitive-guide-to-couchdb.html

...