2010-10-29 5 views
23

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

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

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

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

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

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

Cheers,

Aaron.

+0

Эй Аарон, как вы добились создания новой базы данных каждый раз, когда пользователь подписался? Вы использовали другой уровень, например php, node, ruby? Или вы поняли путь чистого кучаппа? – Costa

ответ

45

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

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

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":[]}}' 

их только пользователь " joe "сможет прочитать базу данных. Для того, чтобы создать пользователя, вы должны иметь уже 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" 

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

ОБНОВЛЕНО: Писатель безопасность

выше метод выдает проблему для чтения, но разрешение читателя здесь на самом деле означает «чтение/запись общих документов», так что это позволяет писать документы для дизайна-документов, за исключением. «Администраторам» в документе _security разрешено писать 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, чтобы получить куки для аутентификации:

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 

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

+0

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

+0

Аарон, приятно видеть, как вы прогрессировали. Читателю в документе _security действительно разрешено писать тоже (я вижу, что это очень пропустимое имя), за исключением проектных документов. Я обновил свой ответ, чтобы подробнее рассказать о разрешениях на запись, включая validade_doc_update и session api. – diogok

+0

У меня есть некоторые пользователи читателей. Я пытаюсь выяснить, как заставить их аутентифицироваться. базовая проверка подлинности работает с завихрением. Я устанавливаю еще один db для аутентификации (что каждый может прочитать)? Затем переадресовываем, _rewrite одного db, указывающего на _rewrite другого? –

5

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

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

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

curl -X PUT http://admin:[email protected]: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:[email protected]:5984/newdatabase 

, а затем

curl -X PUT http://admin:[email protected]: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 не заполняется до тех пор, пока пользователь не будет аутентифицирован. This article предполагает, что все, что вам нужно сделать, это передать полномочия через запрос HTTP в специальную базу данных _SESSION, например, так:

curl -X POST http://username:[email protected]:5984/_session 

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

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

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

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

Спасибо!

Aaron.

+0

Если вы посмотрите, что делает Futon login и logout control, вы увидите общий способ, которым ваши пользователи могут войти в ваше приложение. Если вы получаете доступ через curl, вы можете создавать пользователей, подписавшись на них в Futon. –

+0

При аутентификации вам не нужен префикс «org.couchdb.user», который просто добавлен в _id для хранения в _users db. Просто «curl http: // имя пользователя: пароль @ localhost: 5984/_session», и вы должны получить объект userCtx. – natevw

Смежные вопросы