Security 基于每个数据库的CouchDB授权

Security 基于每个数据库的CouchDB授权,security,couchdb,Security,Couchdb,我正在开发CouchDB支持的应用程序。本质上,我想为我的应用程序的每个用户创建一个数据库。要实现这一点,管理员用户将创建数据库,但接下来,用户将需要访问其数据库(使用HTTP Auth over SSL)。我一直在想这个问题 我找到的最好的资源是CouchDB wiki,位于以下链接: 它建议您可以通过创建一个名为“\u security”的文档来设置每个数据库的授权,您可以在该文档中添加管理员和读卡器的散列。当我尝试创建该文档时,返回的消息是“坏的特殊文档成员:\u security” 任

我正在开发CouchDB支持的应用程序。本质上,我想为我的应用程序的每个用户创建一个数据库。要实现这一点,管理员用户将创建数据库,但接下来,用户将需要访问其数据库(使用HTTP Auth over SSL)。我一直在想这个问题

我找到的最好的资源是CouchDB wiki,位于以下链接:

它建议您可以通过创建一个名为“\u security”的文档来设置每个数据库的授权,您可以在该文档中添加管理员和读卡器的散列。当我尝试创建该文档时,返回的消息是“坏的特殊文档成员:\u security”

任何帮助都将不胜感激

干杯


Aaron.

那条裙子应该没问题

假设您有一个数据库“测试”,并且已经有一个管理员帐户:

curl -X PUT http://localhost:5984/test -u "admin:123"
现在,您可以为其创建_安全文档:

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"
此用户使用sha1和salt“1”(sha1(“123”+“1”))对密码“123”进行哈希运算,因此他可以读取数据库:

curl -X GET http://localhost:5984/test -u "joe:123"
他现在可以阅读数据库中的任何文档,其他用户(除了他和管理员)都不能

更新:写入程序安全性

上面的方法会出现读卡器问题,但是这里的读卡器权限实际上是指“读/写普通文档”,所以它允许写除设计文档之外的文档。_安全文档中的“管理员”可以在此数据库中编写do设计文档

根据您自己的回答,另一种方法是“验证文档更新”,您可以在文件中进行如下验证文档更新:

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'
他们“joe”可以使用基本身份验证写入数据库:

curl -X PUT http://localhost:5984/test/foobar -d '{"foo":"bar"}' -u 'joe:123'
curl http://localhost:5984/_session -v -X POST -d 'name=joe&password=123' -H "Content-Type: application/x-www-form-urlencodeddata"
您还可以使用_会话api获取用于身份验证的cookie:

curl -X PUT http://localhost:5984/test/foobar -d '{"foo":"bar"}' -u 'joe:123'
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=am9lojrdrder1nzq1oj_xiexeftli6ewrbn8iwywodrz”,它们将被验证。

我一直在做更多的研究和测试,我想总结一下我在哪里取得了成果,还有什么对我不起作用

首先,我要向那些读到这个问题的人道歉:我正在寻找为人们设置权限的方法来写入而不是读取数据库。事实证明,这是一个很大的区别:创造“读者”的技术与创造“作家”完全不同(这个词实际上并不存在,但我想知道为什么)

简而言之:您必须向_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哈希方法来获取哈希的\u密码值:

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文件包含一个用于“validate_doc_update”键的Javascript函数,该函数如下所示:

function(new_doc, old_doc, userCtx) {
     if(userCtx.name != username) {
         throw({forbidden: "Please log in first."});
     }
   }
这是迂回的,但有道理。但是,我现在遇到了一个问题:显然,在对用户进行身份验证之前,不会填充userCtx变量。建议您只需通过HTTP请求将凭据传递到特殊会话数据库,如下所示:

curl -X POST http://username:password@localhost:5984/_session
我可以为我的管理员用户这样做,并且将填充userctxvar。但对于我新创建的用户,它失败了:

$ 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散列为null。我想知道是不是名称空间的问题导致了这个问题?里面有个奇怪的冒号,所以密码可能有点混乱?我尝试过在没有名称空间的情况下创建它,但它根本不起作用;至少在这里,我的请求似乎击中了数据库并得到了响应

我被困在这一点上了。如果有人能检查我的假设和迄今为止的进展情况,我希望我们都能弄清楚如何使这项工作发挥作用

谢谢


亚伦。

你可能想看看马特·伍德沃德的《CouchDB身份验证和安全权威指南》

我应该更具体一些。我需要创建用户来写入数据库,而不是读取。但我已经找到了一些答案,所以我现在正在更新我的答案…亚伦,很高兴看到你进步了。_security doc中的读者实际上也可以写(我看这是一个非常不好的标题名),除了设计文档。我已经更新了我的答案,以涵盖更多关于写入权限的内容,包括validade_doc_更新和会话api。我已经设置了一些阅读器用户。我正在努力解决如何让他们进行身份验证。基本身份验证与curl一起工作。我是否设置了另一个db以进行身份验证(每个人都可以读取)?然后重定向,一个db的_重写指向另一个db的_重写?如果你看看Futon登录和注销控件正在做什么,你会看到你的用户可以登录到你的应用程序的一般方式。如果您是通过curl访问的,您可以通过在Futon中以用户身份注册来创建用户。在进行身份验证时,您不需要“org.couchdb.user”前缀,它只是添加到_用户数据库中存储的_id中。简单地
curlhttp://username:password@localhost:5984/_session
你应该得到一个userCtx对象。嘿,亚伦,你是如何在每次用户注册时创建一个新数据库的?您是否使用了另一层,如php、node和ruby?还是你想出了一个纯粹的couchapp方法?