Sitecore 8: xDB – Using a Shared Database User on MongoDB Results in an Exception

When you use authentication with SQL, you have the choice of using a server level user, or a database level user.  Usually, you would choose to use a server level user and grant access to the user per database.  If you want to do the same thing in MongoDB, you can create a user in the admin database, and then grant rights to each individual database that you would want your user to access.  Then, in your connection string, you set the authSource parameter to the admin database, as in:

[code language=”text”]

<add name="analytics" connectionString="mongodb://shareduser:password@10.1.1.15,10.1.1.16/sitecore_analytics?authSource=admin" />

[/code]

If you are using this model on Sitecore 8 with MongoDB, you may come across the following error:

[code language=”text”]
Cannot obtain number of chunks from config database
Exception: MongoDB.Driver.MongoCommandException
Message: Command ‘count’ failed: not authorized on config to execute command { count: "chunks", query: { ns: "sc8prod_analytics.Interactions" } } (response: { "ok" : 0.0, "errmsg" : "not authorized on config to execute command { count: \"chunks\", query: { ns: \"sc8prod_analytics.Interactions\" } }", "code" : 13 })
Source: MongoDB.Driver
at MongoDB.Driver.Operations.CommandOperation`1.Execute(MongoConnection connection)
at MongoDB.Driver.MongoCollection.RunCommandAs[TCommandResult](IMongoCommand command, IBsonSerializer resultSerializer, IBsonSerializationOptions resultSerializationOptions)
at MongoDB.Driver.MongoCollection.RunCommandAs[TCommandResult](IMongoCommand command)
at MongoDB.Driver.MongoCollection.Count(IMongoQuery query)
at Sitecore.Analytics.Data.DataAccess.MongoDb.MongoDbCollectionShardingInformation.GetNumberOfChunks()
at Sitecore.Analytics.Data.DataAccess.MongoDb.MongoDbInteractionStorage.MergeVisits(Guid dyingContactId, Guid survivingContactId)
[/code]

We decompiled the source code and determined the root cause of this to be that the Sitecore code is trying to access the config database (which incidentally may or may not exist).

[code language=”csharp”]
public int GetNumberOfChunks()
{
MongoDatabase sisterDatabase = this.collection.Database.GetSisterDatabase("config");
MongoCollection<BsonDocument> collection = sisterDatabase.GetCollection("chunks");
long num = collection.Count(Query.EQ("ns", this.collection.FullName));
if (num > (long)2147483647)
{
throw new Exception("System has detected too many chunks in the collection.");
}
return (int)num;
}
[/code]

The solution here was to grant the shared user read rights to the config database that didn’t exist:

db.grantRolesToUser(“MONGOUSER”,   [ { role: “read”, db: “config” } ] )