I have created the _users database as well as the _security document and set the security appropriately according to https://cloudant.com/for-developers/faq/auth/.
I have then created a user "test" with role "_reader" however when I try to log in to Cloudant it does not recognize the user.
_users database contains one document:
{
"_id": "test",
"_rev": "1-96973497bc9c89989c4beed02e3f0b96",
"name": "test",
"roles": [
"_reader"
],
"type": "user",
"password": "password"
}
I was then trying to view a design document using username "test" and password "password", as created above, however it did not work.
Within the security document of the database where the design document is located I have:
{ "couchdb_auth_only": true, "members": { "names": [ "test" ], "roles": [ "_reader" ] } }
Any suggestions?
Thanks!
I haven't tested this with Cloudant, and I haven't verified the security of this approach with a cryptography expert (please do this), but hopefully it may point you in the right direction:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;
public class CouchPassword {
public static void main(String[] args) throws NoSuchAlgorithmException {
String password = "123456"; // your password
String salt = genSalt();
password = password + salt;
MessageDigest md = MessageDigest.getInstance("SHA1");
md.update(password.getBytes());
byte byteData[] = md.digest();
System.out.println("Password SHA: " + byteToHexString(byteData) );
System.out.println("Generated Salt: " + salt);
}
public static String genSalt() {
Random ranGen = new SecureRandom();
byte[] salt = new byte[16];
ranGen.nextBytes(salt);
return byteToHexString(salt);
}
public static String byteToHexString(byte[] b) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
sb.append(Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
}
// There are libraries to help with generating SHAs and Hex Strings
// but I have choosen not to use those here so the answer is more standalone.
Password SHA: 316ccb0df3c8bbd8f568347827803682d2c93849
Generated Salt: bba45713ef54016c8ef4b56b6b147936
// _user
{
"_id" : "org.couchdb.user:joe",
"type" : "user",
"name" : "joe",
"roles" : ["standarduser"],
"password_sha" : "316ccb0df3c8bbd8f568347827803682d2c93849",
"salt" : "bba45713ef54016c8ef4b56b6b147936"
}
The roles from the _users
document map to roles defined in the _security
document.
// _security
{
"couchdb_auth_only": true,
"members": {
"names": [],
"roles": ["standarduser"]
},
"admins": {}
}
From the CouchDB documentation
database members - Defined per database. They can read all types of documents from the DB, and they can write (and edit) documents to the DB except for design documents.
database admins - Defined per database. They have all the privileges members have plus the privileges: write (and edit) design documents, add/remove database admins and members, set the database revisions limit (/somedb/_revs_limit API) and execute temporary views against the database (/somedb/_temp_view API). They can not create a database and neither delete a database.
In my example, my user joe
has been given the role standarduser
which maps to a database member for the database.
Note that instead of using roles
, I could have specified member.names
:
// _user document
{
"_id" : "org.couchdb.user:joe",
"type" : "user",
"name" : "joe",
"password_sha" : "316ccb0df3c8bbd8f568347827803682d2c93849",
"salt" : "bba45713ef54016c8ef4b56b6b147936"
}
// _security document
{
"couchdb_auth_only": true,
"members": {
"names": ["joe"],
"roles": []
},
"admins": {}
}
Ensure both member.names
and member.roles
parameters are not empty as this will grant read and write access to everyone:
{
"couchdb_auth_only": true,
"members": {
"names": [],
"roles": []
},
"admins": {}
}
Having no members, any user can write regular documents (any non-design document) and read documents from the database.
Source: http://wiki.apache.org/couchdb/Security_Features_Overview