2010-10-29 4 views
23

Ich arbeite an einer von CouchDB unterstützten Anwendung. Im Wesentlichen möchte ich eine Datenbank für jeden einzelnen Benutzer meiner App erstellen. Um dies zu erreichen, erstellt der Admin-Benutzer die Datenbank, aber in Zukunft muss der Benutzer auf seine Datenbank zugreifen (mithilfe von HTTP Auth über SSL). Ich habe verdammt viel Zeit damit verbracht, dies herauszufinden.CouchDB Autorisierung pro Datenbank Basis

Die beste Ressource, die ich gefunden habe, ist in der CouchDB Wiki, unter diesem Link:

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

Er schlägt vor, dass Sie pro-Datenbank Genehmigung durch die Schaffung eines Dokuments „_Sicherheit“ genannt festlegen können, auf die Sie Füge einen Hash von Admins und Lesern hinzu. Wenn ich versuche, dieses Dokument zu erstellen, ist die Nachricht, die ich zurückbekomme, "Schlechtes spezielles Dokument Mitglied: _Sicherheit".

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

Jede Hilfe wäre willkommen!

Prost,

Aaron.

+0

Hey Aaron, wie haben Sie erreichen bis ein Benutzer unterzeichnet eine neue Datenbank jedes Mal zu schaffen? Hast du eine andere Stufe benutzt, wie PHP, Node, Ruby? Oder hast du einen reinen Couchapp-Weg gefunden? – Costa

Antwort

45

Es sollte kein Problem mit diesem Ansatz sein.

Angenommen, Sie haben eine Datenbank „Test“ haben, und ein Admin-Konto haben bereits:

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

Jetzt können Sie ein _Sicherheit Dokument dafür erstellen:

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

Them nur der Benutzer " Joe "wird in der Lage sein, die Datenbank zu lesen. Um den Benutzer zu erstellen Sie bereits das SHA1-Hash-Passwort haben muss:

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" 

Dieser Benutzer das Passwort "123" gehasht mit SHA1 mit Salz "1" (SHA1 ("123" + "1")), so er kann die Datenbank lesen:

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

er kann jedes Dokument jetzt auf dieser Datenbank lesen, und keinen anderen Benutzer (aber er und admin) kann.

AKTUALISIERT: Schriftsteller Sicherheit

Das obige Verfahren gibt dem Leser Problem, aber der Leser die Erlaubnis hier eigentlich bedeuten „Lesen/Schreiben gemeinsame Dokumente“, so dass es Dokumente zu schreiben, außer für Design-docs ermöglicht. Die "Admins" im _security doc dürfen DoDocs in diese Datenbank schreiben.

Der andere Ansatz, wie er von der eigenen Antwort genommen, ist die „validate_doc_update“, können Sie eine validate_doc_update haben kann als in einer Datei wie folgt vor:

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

und in ein couchdb Entwurf drücken:

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" kann auf die Datenbank unter Verwendung von Standardauthentifizierung schreiben:

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

Wie Sie adressiert auch können Sie die _SESSION api einen Cookie für die Authentifizierung zu erhalten:

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

So können Sie das Cookie enthalten "AuthSession = am9lOjRDRDE1NzQ1Oj_xIexerFtLI6EWrBN8IWYWoDRz":

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

Dieser einen Header wie zurückkehren in Ihren nächsten Anfragen und sie werden authentifiziert.

+0

Ich hätte genauer sein sollen. Ich muss Benutzer erstellen, um * in die Datenbank schreiben, nicht lesen. Aber ich habe einige Antworten darauf gefunden, also aktualisiere ich gerade meine Antwort ... –

+0

Aaron, schön zu sehen, dass du Fortschritte machst. Der Leser im _security doc darf tatsächlich auch schreiben (ich sehe, dass es ein sehr fehlender führender Name ist), außer für Design-Dokumente. Ich habe meine Antwort aktualisiert, um mehr über das Schreiben von Berechtigungen einschließlich des validade_doc_update und der Session-API zu erfahren. – diogok

+0

Ich habe einige Leser Benutzer eingerichtet. Ich versuche herauszufinden, wie man sie authentifizieren kann. Die grundlegende Authentifizierung funktioniert mit curl. Richte ich eine weitere Datenbank für die Authentifizierung ein (die jeder lesen kann)? Dann Redirect, der _rewrite von einem db zeigt auf den _rewrite des anderen? –

5

Ich habe mehr Forschung und Tests gemacht, und ich möchte zusammenfassen, wo ich hingekommen bin, und was immer noch nicht funktioniert für mich.

Zunächst einmal, Entschuldigung für diejenigen, die diese Frage gelesen: Ich suchte nach Möglichkeiten, Berechtigungen für Menschen zu schreiben, nicht zu lesen, die Datenbank. Es stellt sich heraus, dass es ein großer Unterschied ist: Die Techniken zum Erstellen eines "Lesers" sind völlig anders als das Erstellen eines "Schreibers" (dieser Begriff existiert eigentlich nicht, obwohl ich mich frage warum).

Kurz gesagt: Sie müssen der _users-Datenbank einen Benutzer hinzufügen, der eine Liste der Benutzer enthält, die Zugriff auf eine beliebige Datenbank in Ihrer CouchDB-Instanz haben. Ich war in der Lage, das zu tun, indem Sie einen Befehl ähnlich Ausgabe:

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

Hinweis Sie müssen offenbar mit dem „org.couchdb.user“ Präfix den Benutzernamen Namespace. Ich habe ein Ruby-Hashing-Verfahren den hashed_password Wert zu erhalten:

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

Dieses eine scheinbar gültige Benutzer in die Datenbank erhält. Der nächste Schritt ist, diesen Benutzer als "Writer" (ha, da ist es wieder!) Für die neue Datenbank, die ich erstellt habe, zuzuweisen. So könnte ich so etwas wie:

curl -X PUT http://admin:[email protected]:5984/newdatabase 

und dann

curl -X PUT http://admin:[email protected]:5984/newdatabase/_design/security -d @security.json 

Die .json Datei eine Javascript-Funktion für den "validate_doc_update" Schlüssel enthält, und diese Funktion wie folgt aussieht:

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

Es ist Kreisverkehr, aber es macht Sinn. Jetzt stoße ich jedoch auf ein Problem: scheinbar wird die userCtx-Variable nicht gefüllt, bis der Benutzer authentifiziert ist. This article schlägt vor, dass alles, was Sie tun müssen, ist die Anmeldeinformationen über eine HTTP-Anforderung an eine spezielle _SESSION Datenbank übergeben, etwa so:

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

Ich kann für mein Admin-Benutzer tun, und die userCtx var wird aufgefüllt werden.Aber für meine neu erstellte Benutzer, es scheitert:

$ 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"]}} 

Notiere die userCtx Hash null ist. Ich frage mich, ob dieses Namespace-Ding das Problem verursacht? Es hat einen verdammten Doppelpunkt, vielleicht gibt es also etwas Verwirrung über das Passwort? Ich habe versucht, es ohne den Namensraum zu machen, und es funktioniert überhaupt nicht; zumindest hier scheint meine Anfrage die Datenbank zu treffen und eine Antwort zu bekommen.

Ich bin an diesem Punkt fest. Wenn jemand meine Vermutungen und Fortschritte soweit überprüfen kann, hoffe ich, dass wir alle herausfinden können, wie wir das machen können.

Danke!

Aaron.

+0

Wenn Sie sich ansehen, was die Futon- Ein- und Ausloggensteuerung bewirkt, sehen Sie eine allgemeine Möglichkeit, wie sich Ihre Benutzer in Ihre App einloggen können. Wenn Sie über curl zugreifen, können Sie Benutzer erstellen, indem Sie sich in Futon anmelden. –

+0

Sie benötigen nicht das Präfix "org.couchdb.user" beim Authentifizieren, das nur zur _id für den Speicher in der _users db hinzugefügt wird. Einfach 'curl http: // Benutzername: Passwort @ localhost: 5984/_session' und Sie sollten ein userCtx-Objekt erhalten. – natevw

Verwandte Themen