Unable to connect to MongoDb (using authentication) using mongocsharpdriver 2.7.0

一曲冷凌霜 提交于 2021-01-29 14:13:23

问题


I have created a sample c# console application to connect to mongodb hosted on CentOS machine on a docker.

The command used to create container is below:

docker run -d --name mongodb-container -p 2020:27017 -v /home/mongodb_data:/var/lib/mongodb/data -v /home/mongodb_log:/var/log/mongodb -v /home/mongod.conf:/etc/mongod.conf -e MONGO_INITDB_ROOT_USERNAME=mongoadmin -e MONGO_INITDB_ROOT_PASSWORD=secret mongo

System IP: 172.17.103.158
Mongodb docker port: 2020

Now coming to c# code

class users
    {
        [BsonId]
        public ObjectId _Id { get; set; }

        [BsonElement]
        public string name { get; set; }
    }

MongoContext Class

public class MongoContext
    {
        IMongoClient _client;
        public readonly IMongoDatabase _database;

        public MongoContext()
        {
            MongoCredential credential = MongoCredential.CreateCredential(ConfigurationManager.AppSettings["MongoDatabaseName"], ConfigurationManager.AppSettings["MongoUsername"], ConfigurationManager.AppSettings["MongoPassword"]);

            var settings = new MongoClientSettings
            {
                Credential = credential,
                VerifySslCertificate = false,
                ConnectionMode = ConnectionMode.ReplicaSet,
                ReplicaSetName = ConfigurationManager.AppSettings["MongoDatabaseName"],
                UseSsl = false,
                Server = new MongoServerAddress(ConfigurationManager.AppSettings["MongoHost"], Convert.ToInt32(ConfigurationManager.AppSettings["MongoPort"]))
            };

            _client = new MongoClient(settings);
            _database = _client.GetDatabase(ConfigurationManager.AppSettings["MongoDatabaseName"]);
        }
    }

Web Config:

<configuration>


<appSettings>
    <add key="MongoDatabaseName" value="clientdb" />
    <add key="MongoUsername" value="mongoadmin" />
    <add key="MongoPassword" value="secret" />
    <add key="MongoPort" value="2020" />
    <add key="MongoHost" value="172.17.103.158" />
  </appSettings>

</configuration>

Viewing Users

static List<users> ViewUsers()
    {
        try
        {
            MongoContext db = new MongoContext();
            IMongoCollection<users> Table1 = db._database.GetCollection<users>("users");

            return Table1.AsQueryable().ToList();
        }
        catch (Exception ex) { throw ex; }
    }

Error:

{"A timeout occured after 30000ms selecting a server using CompositeServerSelector{
  Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{
    AllowedLatencyRange = 00:00:00.0150000 } }.
Client view of cluster state is {
  ClusterId : \"1\",
  ConnectionMode : \"Automatic\",
  Type : \"Unknown\",
  State : \"Disconnected\",
  Servers : [{
    ServerId: \"{
      ClusterId : 1,
      EndPoint : \"172.17.103.158:2020\" }\",
    EndPoint: \"172.17.103.158:2020\",
    State: \"Disconnected\",
    Type: \"Unknown\",
    HeartbeatException: \"MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. 
        ---> MongoDB.Driver.MongoAuthenticationException: Unable to authenticate using sasl protocol mechanism SCRAM-SHA-1. 
        ---> MongoDB.Driver.MongoCommandException: Command saslStart failed: Authentication failed..\r\n   
      at MongoDB.Driver.Core.WireProtocol.CommandUsingQueryMessageWireProtocol`1.ProcessReply(ConnectionId connectionId, ReplyMessage`1 reply)\r\n   
      at MongoDB.Driver.Core.WireProtocol.CommandUsingQueryMessageWireProtocol`1.<ExecuteAsync>d__14.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
      at MongoDB.Driver.Core.Authentication.SaslAuthenticator.<AuthenticateAsync>d__7.MoveNext()\r\n   --- End of inner exception stack trace ---\r\n   
      at MongoDB.Driver.Core.Authentication.SaslAuthenticator.<AuthenticateAsync>d__7.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
      at MongoDB.Driver.Core.Authentication.DefaultAuthenticator.<AuthenticateAsync>d__7.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
      at MongoDB.Driver.Core.Authentication.AuthenticationHelper.<AuthenticateAsync>d__1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
      at MongoDB.Driver.Core.Connections.ConnectionInitializer.<InitializeConnectionAsync>d__3.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
      at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()\r\n   --- End of inner exception stack trace ---\r\n   
      at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
      at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n   
      at MongoDB.Driver.Core.Servers.ServerMonitor.<HeartbeatAsync>d__27.MoveNext()\" }] }."}

In Short Error Message:

{"A timeout occured after 30000ms selecting a server using CompositeServerSelector{
  Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{
    AllowedLatencyRange = 00:00:00.0150000 } }.
Client view of cluster state is {
  ClusterId : \"1\",
  ConnectionMode : \"Automatic\",
  Type : \"Unknown\",
  State : \"Disconnected\",
  Servers : [{
    ServerId: \"{
      ClusterId : 1,
      EndPoint : \"172.17.103.158:2020\" }\",
    EndPoint: \"172.17.103.158:2020\",
    State: \"Disconnected\",
    Type: \"Unknown\",
    HeartbeatException: \"MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. 
      ---> MongoDB.Driver.MongoAuthenticationException: Unable to authenticate using sasl protocol mechanism SCRAM-SHA-1. 
      ---> MongoDB.Driver.MongoCommandException: Command saslStart failed: Authentication failed..

I am facing this issue when mongo db is being protect by username and password otherwise not.

Altough MongoDb Compass is still able to connect to mongo db in both the cases.

My Question is : Why c# code is not getting connecting to mongodb when authentication is applied on db.

Solutions Tried:

  1. Connected using uri:

    mongodb://mongoadmin:secret@172.17.103.158:2020/clientdb
    
  2. Edited mongod.config => BindIp 127.0.0.1, 172.17.103.17 (My system IP)

  3. Using SCRAM-SHA-1 mechanism

回答1:


Follow this link Mongo Site and look at Section

The Database Component :
The database component is optional and is used to indicate which database to authenticate against. When the database component is not provided, the “admin” database is used.

The issue is you are authenticating the mongoadmin user for clientdb. But mongoadmin user is authenticated to admin db. Get the mongoadmin user authenticated and then you can access clientdb.

Below is the sample using URI method:

        IMongoClient _client;
        public readonly IMongoDatabase _database;

        public MongoContext_URIBased()
        {
            var mongoUrl = new MongoUrl("mongodb://mongoadmin:secret@172.17.103.158:2020/admin");
            _client = new MongoClient(mongoUrl);
            _database = _client.GetDatabase("clientdb");
        } 

And According to your code , below will work:

Your config file should be like:

<appSettings>
<add key="MongoMasterDatabaseName" value="admin" />
<add key="MongoUsername" value="mongoadmin" />
<add key="MongoPassword" value="secret" />
<add key="MongoPort" value="2020" />
<add key="MongoHost" value="172.17.103.158" />
<add key="MongoClientDatabaseName" value="clientDb" />


</appSettings>

And C# code :

public class MongoContext
    {
        IMongoClient _client;
        public readonly IMongoDatabase _database;

        public MongoContext()
        {
            MongoCredential credential = MongoCredential.CreateCredential(ConfigurationManager.AppSettings["MongoMasterDatabaseName"], ConfigurationManager.AppSettings["MongoUsername"], ConfigurationManager.AppSettings["MongoPassword"]);
            var settings = new MongoClientSettings
            {
                Credential = credential,
                Server = new MongoServerAddress(, Convert.ToInt32(ConfigurationManager.AppSettings["MongoPort"]))
            };
            _client = new MongoClient(settings);
            _database = _client.GetDatabase(ConfigurationManager.AppSettings["MongoClientDatabaseName"]);
        }
    }

As you can see, mongoadmin user is getting authenticated to admin db first. Then you can connect to clientdb




回答2:


in mongod.conf add your local ip to bind_ip

  • mongod.conf File

    bind_ip = 127.0.0.1,192.168.xxx.xxxx

where:

  • 127.0.0.1 to allow connection from same machine
  • 192.168.xxx.xxxx to allow connection from this ip

Check This

Make sure the username you are using is exist in clientdb database

to add user to clientdb database you can user following

use clientdb

db.createUser(
   {
     user: "mongoadmin",
     pwd: "secret",
     roles:
       [
         { role: "root", db: "admin" }
       ]
   }
)


来源:https://stackoverflow.com/questions/53756773/unable-to-connect-to-mongodb-using-authentication-using-mongocsharpdriver-2-7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!