Why Can't I Authenticate?

I’m using the driver in Nodejs without Mongoose or any such extra layers. In the following procedures, everything comes from the manual, and it looks as though I am specifying the right credentials (user, password, and database), but nevertheless, an error message comes back “MongoError: command insert requires authentication”.

The same server has another database with its own user, and those are working with software that I installed, but didn’t write. The data about the users in the “admin” database looks parallel between the two of them.

Here I specify the username and password in the arguments to the “connect” operation rather than in the connection URI as I have seen in some examples. Does sending them this way simply not work? What else is there to investigate to try to explain why I am getting an error message that mentions authentication?

app.db_uri = "mongodb://127.0.0.1:27017";

typeof (app.MongoClient = require("mongodb").MongoClient);

typeof ( app.mongo_client = new app.MongoClient(
  app.db_uri, {useUnifiedTopology: true}
) );

( async function () { with (app) {
  try {
    await mongo_client.connect({
      'auth.user': "archive",
      'auth.password': db_pw,
      authSource: "archive"
    });
    console.log("Connected.");
  } catch (err) {
    console.error(err)
  }
}})();

with (app) typeof (self.db = mongo_client.db("archive"));

( async function () { with (app) {
  try {
    self.tst_coll = await db.collection("tst");
    console.log("Have handle to collection.");
  } catch (err) {
    console.error(err)
  }
}})();

( async function () { with (app) {
  try {
    await tst_coll.bulkWrite(
      [
        { insertOne: { document: {
          black: 'lives',
          matter: ['you', 'bet']
        }}}
      ]
    );
    console.log("Wrote.");
  } catch (err) {
    console.error(err)
  }
}})();

MongoError: command insert requires authentication.

Are you sure the user was created in the archive namespace? Often the authSouce is admin.

I would assume an error would show with your try…catch though vs “Connected.”

I attempted administration both via the nodejs driver and via the mongo shell. In the latter:

> tmp.arch = tmp.cl.getDB("archive")
archive
> tmp.arch.changeUserPassword("archive", "egg}bosEv7")
> 

In the mongo shell:

> with (tmp) self.r = archive.getUser( "archive", {
...    showCredentials: true,
...    showPrivileges: true,
...    showAuthenticationRestrictions: true
...    /* no filter */
... } )
{
	"_id" : "archive.archive",
	"userId" : UUID("774f51d9-1a44-4505-8459-5254c767591d"),
	"user" : "archive",
	"db" : "archive",
	"mechanisms" : [
		"SCRAM-SHA-1",
		"SCRAM-SHA-256"
	],
	"credentials" : {
		"SCRAM-SHA-1" : {
			"iterationCount" : 10000,
			"salt" : "ofZDQzZpxlNuIaLZBCgZcA==",
			"storedKey" : "bnKjAub+8gK8abOTk2pv1xZCp4c=",
			"serverKey" : "2iYaWdHyR5oqpkb8oGxhRcXWgAA="
		},
		"SCRAM-SHA-256" : {
			"iterationCount" : 15000,
			"salt" : "tQaoqzDL+7z7Lwm9ueAuqDqMWrMEuoq0n8+KKg==",
			"storedKey" : "2E+qP66fRuIdluy+5AV4p+cvo7HhhjMR5H3DASL+258=",
			"serverKey" : "cw3hd4SpOJw7QbGYBAWIbB6bKWvP0V/ArSxKXJfd7oY="
		}
	},
	"customData" : {
		
	},
	"roles" : [
		{
			"role" : "readWrite",
			"db" : "archive"
		}
	],
	"inheritedRoles" : [
		{
			"role" : "readWrite",
			"db" : "archive"
		}
	],
	"inheritedPrivileges" : [
		{
			"resource" : {
				"db" : "archive",
				"collection" : ""
			},
			"actions" : [
				"changeStream",
				"collStats",
				"convertToCapped",
				"createCollection",
				"createIndex",
				"dbHash",
				"dbStats",
				"dropCollection",
				"dropIndex",
				"emptycapped",
				"find",
				"insert",
				"killCursors",
				"listCollections",
				"listIndexes",
				"planCacheRead",
				"remove",
				"renameCollectionSameDB",
				"update"
			]
		},
		{
			"resource" : {
				"db" : "archive",
				"collection" : "system.indexes"
			},
			"actions" : [
				"changeStream",
				"collStats",
				"dbHash",
				"dbStats",
				"find",
				"killCursors",
				"listCollections",
				"listIndexes",
				"planCacheRead"
			]
		},
		{
			"resource" : {
				"db" : "archive",
				"collection" : "system.js"
			},
			"actions" : [
				"changeStream",
				"collStats",
				"convertToCapped",
				"createCollection",
				"createIndex",
				"dbHash",
				"dbStats",
				"dropCollection",
				"dropIndex",
				"emptycapped",
				"find",
				"insert",
				"killCursors",
				"listCollections",
				"listIndexes",
				"planCacheRead",
				"remove",
				"renameCollectionSameDB",
				"update"
			]
		},
		{
			"resource" : {
				"db" : "archive",
				"collection" : "system.namespaces"
			},
			"actions" : [
				"changeStream",
				"collStats",
				"dbHash",
				"dbStats",
				"find",
				"killCursors",
				"listCollections",
				"listIndexes",
				"planCacheRead"
			]
		}
	],
	"inheritedAuthenticationRestrictions" : [ ],
	"authenticationRestrictions" : [ ]
}

Try passing the auth options as a document vs dot notation, worked for me experimenting with node REPL:

{
  "auth":{
    "user":"archive",
    "password":"whatever it is"
  },
  "authSource": "archive"
}
1 Like

I tried the breakdown you suggested, but got the same result as before.

I have mongodb driver 3.6.3, nodejs12.18.3.

$ mongod --version
db version v4.0.21
git version: 3f68a848c68e993769589dc18e657728921d8367
OpenSSL version: OpenSSL 1.1.1  11 Sep 2018
allocator: tcmalloc
modules: none
build environment:
    distmod: ubuntu1804
    distarch: x86_64
    target_arch: x86_64

Update: I changed the password so it would not need percent encoding to be included in the URI. Then I moved the username, password, and default database for authentication into the URI. That way, it worked. Therefore, there was nothing wrong with the administrative setup.

What node, what mongodb, and what mongod?

node v15.2.0 , mongodb driver 3.6.3, mongo 4.4

I am a bit busy now, but I might have time later to replicate and then try with a setup similar to yours.

Thanks; I think you need not imitate my setup; I will either try yours or if I see that your versions are later than mine, I may just assume someone solved it in them.

Comparing, I see that we have the same driver, but you have a later DBMS. I doubt whether the nodejs matters.

I actually control two VMs, one for the app I am working on and another for my personal use. I can easily experiment with different DBMS versions on the latter and it won’t put any risk on the app.

@Jack_WAUGH
So the problem was presumably for the password not being ascii encoded, right?

May I ask what was the character and how where you encoding it?

No, I’m thinking that the problem is linked to my passing the username and password as arguments rather than in the URI. Note that in my original example, the URI only specified the host and port.

I see, thanks. So if you tried use archive; db.auth(username, password) it did work? (sorry if I missed smth).

use archive looks like a mongo shell thing. I am doing all the user operations from nodejs (with just the straight driver, no Mongoose).

What worked was encoding the username and password into the connection URI instead of passing them with the mongo_client.connect(...) call. [edit] I assume that when they are passed this way, no encoding is necessary. In any event, the original password I tried had a right curly
brace in it ("}") and otherwise only digits and Latin letters.

1 Like