MongoDB 2.8 authentication mechanism changes


Mongodb 2.8 brings some welcome and exciting changes. One thing to note however, is the client authentication model has changed and may require some code changes albeit minor.

The drivers

The release notes mention that SCRAM-SHA-1 will replace Mongo-CR as the new challenge-response mechanism. A couple key differences should be noted and are documented in SERVER-7596. All drivers will now ensure they use the new protocol when connecting to 2.8 servers. The new drivers are smart enough to fall back to the old Mongo-CR mechanism when connecting to 2.6.x and previous server versions. They automatically use the SCRAM-SHA-1 mechanism when connecting to 2.8.x and above versions. This would seem very nice and tidy, but there is a caveat.

For example, in java driver version 2.13 the method to authenticate has changed. So your code will need to be updated to utilize the new method when connecting to ANY database when you use the new driver. If you use the older drivers they don’t speak SCRAM-SHA-1 and thus can’t connect to any 2.8.x+ server versions. This is all fairly well documented, but not super clear in the release notes.

The old code may look something like this:

import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
...
public static void main (String[] args) throws Exception {
    ...
    ServerAddress srvrAdd = new ServerAddress(serverName,serverPort);
    MongoCredential credential = MongoCredential.createMongoCRCredential(userName, dbName, passWord.toCharArray());
    MongoClient m = new MongoClient(srvrAdd, Arrays.asList(credential));
...
}
...

This should be changed to use the new method as:

import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
...
public static void main (String[] args) throws Exception {
    ...
    ServerAddress srvrAdd = new ServerAddress(serverName,serverPort);
    // change below line
    MongoCredential credential = MongoCredential.createCredential(userName, dbName, passWord.toCharArray());
    MongoClient m = new MongoClient(srvrAdd, Arrays.asList(credential));
...
}
...

Essentially all code needs to have createMongoCRCredential replaced with createCredential in order to authenticate with 2.8 server versions. createMongoCRCredential still exists, but has no mechanism to utilize SCRAM-SHA-1 and thus the change. Depending on your editor it can be a simple find/replace because they work the exact same way. Or you can run something like this:


sed -i 's/createMongoCRCredential/createCredential/g' *.java

This is all pre-2.8 release stuff, so things could change before the GA release of 2.8, so keep that in mind. The docs aren’t written (as of today) I haven’t played with all the drivers yet, but at does appear that Python does not require any changes to any code utilizing the driver as the Authenticate method has been changed to accomodate the new mechanism.

The Server

Lastly, there seems to be the ability to tell the server what authentication mechanism you would like to default to using something like:

--setParameter authenticationMechanisms=MONGODB-CR

But it appears that the setting will end up triggering the system to use SCRAM-SHA-1 even when set to MONGODB-CR. This is perplexing even after considering the notes in the code. It appears no way to set a 2.8 server to use MONGODB-CR at the server level when using server version 2.8.

// For backwards compatibility, in 2.8 we are letting MONGODB-CR imply general
// challenge-response auth and hence SCRAM-SHA-1 is enabled by either specifying
// SCRAM-SHA-1 or MONGODB-CR in the authenticationMechanism server parameter.
if (!sequenceContains(saslGlobalParams.authenticationMechanisms, "SCRAM-SHA-1") &&
    sequenceContains(saslGlobalParams.authenticationMechanisms, "MONGODB-CR"))
    saslGlobalParams.authenticationMechanisms.push_back("SCRAM-SHA-1");