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

标签 c# mongodb docker asp.net-core-2.0 mongodb-.net-driver

我创建了一个示例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=secret mongo



系统IP:172.17.103.158
Mongodb Docker端口:2020

现在来C#代码
class users
    {
        [BsonId]
        public ObjectId _Id { get; set; }

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

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"]);
        }
    }

网络配置:
<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>

查看用户
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; }
    }

错误:
{"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()\" }] }."}

简短的错误消息:
{"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..

当mongo db受用户名和密码保护时,否则我将面临此问题。

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

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

尝试过的解决方案:
  • 使用uri连接:
    mongodb://mongoadmin:secret@172.17.103.158:2020/clientdb
    
  • 编辑的mongod.config => BindIp 127.0.0.1, 172.17.103.17(我的系统IP)
  • 使用SCRAM-SHA-1机制
  • 最佳答案

    点击此链接Mongo Site
    然后看一节

    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.



    问题是您正在验证clientdb的mongoadmin用户。但是mongoadmin用户已通过admin db的身份验证。获取mongoadmin用户的身份验证,然后您可以访问clientdb。

    下面是使用URI方法的示例:
            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");
            } 
    

    根据您的代码,下面将起作用:

    您的配置文件应类似于:
    <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>
    

    和C#代码:
    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"]);
            }
        }
    

    如您所见,mongoadmin用户首先要获得对admin db的身份验证。然后您可以连接到clientdb

    关于c# - 无法使用mongocsharpdriver 2.7.0连接到MongoDb(使用身份验证),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53756773/

    相关文章:

    node.js - mongodb 获取最喜欢帖子的用户

    git - 由于 "port 443: Connection timed out",Docker 构建失败

    c# - Moq When(Func<bool>) 方法的使用

    php - 如何获取 MongoDB PHP 中的特定字段?

    c# - Unity 中的按钮,不使用 UI?

    mongodb - 在 MongoDB 中投票

    docker - 无法访问共享数据量

    docker - 自动化docker commit和push

    C# 泛型实例化

    c# - Watin DialogHandler 关闭 SaveFileDialog