OPTIONS

Implement Authentication in a Driver

Note

This legacy documentation does not necessarily reflect the current practices in MongoDB driver implementation, but may be useful for historical purposes. See the MongoDB Meta Driver for the current documentation of MongoDB driver implementation.

Overview

The current version of MongoDB supports only the very basic authentication of a username and password for a particular database. Once authenticated, the user has full read and write access to that database.

The exception is the authentication for the admin database. Authentication on the admin database gives the user read and write access to all databases on the server. Effectively, admin access means root access to the database.

Note

On a single socket, it is possible to authenticate for any number of databases and as different users. This authentication persists for the life of the database connection, barring a logout command.

Authentication Process

Authentication is a two step process:

  1. The driver runs a getnonce command to get a nonce for use in the subsequent authentication, as in the following example in the mongo shell:

    db.$cmd.findOne( { getnonce: 1} )
    

    The result of the command displays the nonce as a hexadecimal String:

    { "nonce" : "7ca422a24f326f2a", "ok" : 1 }
    
  2. The driver then runs the authenticate command for the database on which to authenticate.

    The authenticate command has the following syntax:

    db.runCommand( { authenticate : 1, user : <username>, nonce : <nonce>, key : <digest> }
    
    • <username> is a username in the database’s system.users collection.
    • <nonce> is the nonce returned from a previous getnonce step.
    • <digest> is the hex encoding of an MD5 message digest.
      • The MD5 message digest is the MD5 hash of the concatenation of <nonce>, <username>, <password_digest>.
      • The <password_digest> is the value in the pwd field associated with the <username> in the database’s system.users collection. The pwd is the hex encoding of MD5( <username> + ":mongo:" + <password_text> ).

    The result of the command should display:

    { "ok" : 1 }
    

    If the authentication fails, you can review the details in the MongoDB server log files.

Consider the following implementation of authentication that uses the MongoDB JavaScript driver:

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;
}

Logout

Drivers may implement the logout command which, for the connection, deauthorizes the usage for the specified database. Other databases may still be authorized.

db.$cmd.findOne( { logout: 1 } )

The result of the command should display:

{ "ok" : 1 }

Alternatively, you can close the socket to deauthorize.

Replica Sets and Authentication

For drivers that support replica sets, authentication requires additional considerations:

  • When switching from one server in a replica set to another, such as in a failover situation, you must re-authenticate. Clients might consider caching authentication from the user so that the clients can re-authenticate with the new server when appropriate.
  • Logging out from some but not all members of a replica set could be problematic.
  • Authenticating with a server in slave mode is allowed.