Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
998 views
in Technique[技术] by (71.8m points)

security - CouchDB Authorization on a Per-Database Basis

I'm working on an application supported by CouchDB. Essentially, I want to create a database for each individual user of my app. To accomplish this, the admin user will create the database, but going forward, the user will need to access their database (using HTTP Auth over SSL). I've been having a hell of a time figuring this out.

The best resource I have found is in the CouchDB wiki, at this link:

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

It suggests that you can set per-database authorization by creating a document called "_security" to which you add a hash of admins and readers. When I attempt to create that document, the message I get back is "Bad special document member: _security".

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

Any help would be appreciated!

Cheers,

Aaron.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There should be no problem with that aproach.

Let's say you have a database "test", and have an admin account already:

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

Now you can create a _security document for it:

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

Them only the user "joe" will be able to read the database. To create the user you must have already the sha1 hashed password:

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"

This user have the password "123" hashed using sha1 with salt "1" (sha1("123"+"1")), so he can read the database:

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

He can read any document now on that database, and no other user (but him and admin) can.

UPDATED: Writer security

The above method issues the reader problem, but the reader permission here actually mean "read/write common docs", so it allows to write docs except for design-docs. The "admin"s in the _security doc are allowed to write do design-docs in this database.

The other approach, as taken from your own answer, is the "validate_doc_update", you can have a validate_doc_update as follow in a file:

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

And push it into a couchdb design:

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'

Them "joe" can write to the database using Basic Authentication:

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

As you also addressed you can use the _session api to get a cookie for authentication:

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

This will return a header like:

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

So you can include the cookie "AuthSession=am9lOjRDRDE1NzQ1Oj_xIexerFtLI6EWrBN8IWYWoDRz" in your next requests and they will be authenticated.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...