问题
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:
Connected using uri:
mongodb://mongoadmin:secret@172.17.103.158:2020/clientdb
Edited
mongod.config
=>BindIp 127.0.0.1, 172.17.103.17
(My system IP)- 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