无法使用 mongocsharpdriver 2.7.0 连接到 MongoDb(使用身份验证)

Arj*_*jun 3 c# mongodb docker mongodb-.net-driver asp.net-core-2.0

我创建了一个示例 c# 控制台应用程序来连接到 Docker 上的 CentOS 计算机上托管的 mongodb。

用于创建容器的命令如下:

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=秘密 mongo

系统IP:172.17.103.158
Mongodb docker端口:2020

现在来看看 C# 代码

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

        [BsonElement]
        public string name { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

MongoContext 类

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"]);
        }
    }
Run Code Online (Sandbox Code Playgroud)

网页配置:

<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>
Run Code Online (Sandbox Code Playgroud)

查看用户

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; }
    }
Run Code Online (Sandbox Code Playgroud)

错误:

{"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()\" }] }."}
Run Code Online (Sandbox Code Playgroud)

简而言之错误消息:

{"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..
Run Code Online (Sandbox Code Playgroud)

当 mongo db 受到用户名和密码保护时,我遇到这个问题,否则不会。

尽管 MongoDb Compass 在这两种情况下仍然能够连接到 mongo db。

我的问题是:为什么在数据库上应用身份验证时,c# 代码无法连接到 mongodb。

尝试过的解决方案:

  1. 使用 uri 连接:

    mongodb://mongoadmin:secret@172.17.103.158:2020/clientdb
    
    Run Code Online (Sandbox Code Playgroud)
  2. 编辑mongod.config=> BindIp 127.0.0.1, 172.17.103.17(我的系统IP)

  3. 使用SCRAM-SHA-1机制

小智 7

点击此链接Mongo Site \n并查看部分

\n\n
\n

数据库组件 :
\n 数据库组件是可选的,用于指示要针对哪个数据库进行身份验证。如果未提供数据库组件,则使用 \xe2\x80\x9cadmin\xe2\x80\x9d 数据库。

\n
\n\n

问题是您正在验证 clientdb 的 mongoadmin 用户。但 mongoadmin 用户已通过管理数据库身份验证。让 mongoadmin 用户经过身份验证,然后就可以访问 clientdb。

\n\n

下面是使用 URI 方法的示例:

\n\n
        IMongoClient _client;\n        public readonly IMongoDatabase _database;\n\n        public MongoContext_URIBased()\n        {\n            var mongoUrl = new MongoUrl("mongodb://mongoadmin:secret@172.17.103.158:2020/admin");\n            _client = new MongoClient(mongoUrl);\n            _database = _client.GetDatabase("clientdb");\n        } \n
Run Code Online (Sandbox Code Playgroud)\n\n

根据您的代码,以下内容将起作用:

\n\n

你的配置文件应该是这样的:

\n\n
<appSettings>\n<add key="MongoMasterDatabaseName" value="admin" />\n<add key="MongoUsername" value="mongoadmin" />\n<add key="MongoPassword" value="secret" />\n<add key="MongoPort" value="2020" />\n<add key="MongoHost" value="172.17.103.158" />\n<add key="MongoClientDatabaseName" value="clientDb" />\n\n\n</appSettings>\n
Run Code Online (Sandbox Code Playgroud)\n\n

和 C# 代码:

\n\n
public class MongoContext\n    {\n        IMongoClient _client;\n        public readonly IMongoDatabase _database;\n\n        public MongoContext()\n        {\n            MongoCredential credential = MongoCredential.CreateCredential(ConfigurationManager.AppSettings["MongoMasterDatabaseName"], ConfigurationManager.AppSettings["MongoUsername"], ConfigurationManager.AppSettings["MongoPassword"]);\n            var settings = new MongoClientSettings\n            {\n                Credential = credential,\n                Server = new MongoServerAddress(, Convert.ToInt32(ConfigurationManager.AppSettings["MongoPort"]))\n            };\n            _client = new MongoClient(settings);\n            _database = _client.GetDatabase(ConfigurationManager.AppSettings["MongoClientDatabaseName"]);\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

如您所见,mongoadmin 用户首先通过管理数据库的身份验证。然后就可以连接clientdb了

\n