[confluence] MongoDB > Implementing Authentication in a Driver

10 views
Skip to first unread message

nor...@mongodb.onconfluence.com

unread,
Jan 16, 2013, 8:05:00 PM1/16/13
to mongodb...@googlegroups.com

Implementing Authentication in a Driver

Page edited by Sam Kleinman


Changes (3)

The current version of Mongo supports only very basic authentication.  One authenticates a username and password in the context of a particular database.  Once authenticated, the user has full read and write access to the database in question.
{redirect:http://docs.mongodb.org/meta-driver/latest/legacy/implement-authentication-in-driver}
The {{admin}} database is special.  In addition to several commands that are administrative being possible only on {{admin}}, authentication on {{admin}} gives one read and write access to all databases on the server.  Effectively, {{admin}} access means root access to the db.

Note on a single socket we may authenticate for any number of databases, and as different users.  This authentication persists for the life of the database connection (barring a {{logout}} command).


h2. The Authentication Process


Authentication is a two step process.  First the driver runs a {{getnonce}} command to get a nonce for use in the subsequent authentication.  We can view a sample {{getnonce}} invocation from {{dbshell}}:
{code}> db.$cmd.findOne({getnonce:1})
{ "nonce":"7268c504683936e1" , "ok":1
{code}The nonce returned is a hex String.

The next step is to run an {{authenticate}} command for the database on which to authenticate.  The authenticate command has the form:

{code}{ authenticate : 1, user : username, nonce : nonce, key : digest }
{code}where
* _username_ is a username in the database's system.users collection;
* _nonce_ is the nonce returned from a previous getnonce command;
* _digest_ is the hex encoding of a MD5 message digest which is the MD5 hash of the concatenation of (_nonce_, _username_, _password_digest_), where _password_digest_ is the user's password value in the {{pwd}} field of the associated user object in the database's system.users collection.  {{pwd}} is the hex encoding of  MD5( username + ":mongo:" \+ _password_text_).

Authenticate will return an object containing
{code}{ ok : 1 }
{code}when successful.

Details of why an authentication command failed may be found in the Mongo server's log files.

The following code from the Mongo Javascript driver provides an example implementation:

{code}DB.prototype.addUser = function( username , pass ){
var c = this.getCollection( "system.users" );

var u = c.findOne( { user : username } ) || { user : username };
u.pwd = hex_md5( username + ":mongo:" + pass );
print( tojson( u ) );

c.save( u );
}

DB.prototype.auth = function( username , pass ){
var n = this.runCommand( { getnonce : 1 } );

var a = this.runCommand(
{
authenticate : 1 ,
user : username ,
nonce : n.nonce ,
key : hex_md5( n.nonce + username + hex_md5( username + ":mongo:" + pass ) )
}
);

return a.ok;
}
{code}
h2. Logout

Drivers may optionally implement the logout command which deauthorizes usage for the specified database for this connection.  Note other databases may still be authorized.

Alternatively, close the socket to deauthorize.

{code}> db.$cmd.findOne({logout:1})
{  
"ok" : 1.0
}
{code}
h2. Replica Sets and Authentication

For drivers that support replica sets, extra care with replication is required.

When switching from one server in a replica set to another, for example in a failover situation, you must reauthenticate. Clients will likely want to cache authentication from the user so that the client can reauthenticate with the new server when appropriate.

Be careful also with operations such as Logout. If you log out from only some members of a replica set, that could be an issue.

Authenticating with a server in slave mode is allowed.

h2. See Also

* [Security and Authentication]

Full Content

nor...@mongodb.onconfluence.com

unread,
Jan 16, 2013, 8:05:00 PM1/16/13
to mongodb...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages