【问题标题】:Connection to MongoDB with authentication fails通过身份验证连接到 MongoDB 失败
【发布时间】:2015-12-22 11:04:50
【问题描述】:

我在第 3 版中使用 MongoDB,并创建了一个名为“logMonitor”的数据库并创建了一个用户,例如:

{
    "_id" : "logMonitor.log",
    "user" : "log",
    "db" : "logMonitor",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "logMonitor"
        }
    ]
}

当我使用用户“log”通过shell连接到数据库时,它返回success,就像这样:

[jboss@chonggouapp mongodb]$ mongo logMonitor -u "log" -p "log"

MongoDB shell 版本:3.0.6

连接到:logMonitor

但是使用以下代码通过 Java 连接失败。

    ServerAddress addr = new ServerAddress("10.46.20.65", 27017);
    
    MongoCredential credential = MongoCredential.createMongoCRCredential(
            "log", "logMonitor", "log".toCharArray());
    
    MongoClientOptions options = MongoClientOptions.builder()
            .serverSelectionTimeout(1000)
            .build();
    MongoClient mongoClient = new MongoClient(addr, Arrays.asList(credential), options);
    
    MongoDatabase db = mongoClient.getDatabase("logMonitor");
    
    long c = db.getCollection("sysLog").count();

引发以下异常:

Exception in thread "main" com.mongodb.MongoTimeoutException: Timed out after 1000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. Client view of cluster state is {type=UNKNOWN, servers=[{address=10.46.20.65:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSecurityException: Exception authenticating}, caused by {com.mongodb.MongoCommandException: Command failed with error 18: 'auth failed' on server 10.46.20.65:27017. The full response is { "ok" : 0.0, "errmsg" : "auth failed", "code" : 18 }}}]
    at com.mongodb.connection.BaseCluster.createTimeoutException(BaseCluster.java:370)
    at com.mongodb.connection.BaseCluster.selectServer(BaseCluster.java:101)
    at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:75)
    at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:71)
    at com.mongodb.binding.ClusterBinding.getReadConnectionSource(ClusterBinding.java:63)
    at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:65)
    at com.mongodb.operation.CountOperation.execute(CountOperation.java:172)
    at com.mongodb.operation.CountOperation.execute(CountOperation.java:43)
    at com.mongodb.Mongo.execute(Mongo.java:738)
    at com.mongodb.Mongo$2.execute(Mongo.java:725)
    at com.mongodb.MongoCollectionImpl.count(MongoCollectionImpl.java:167)
    at com.mongodb.MongoCollectionImpl.count(MongoCollectionImpl.java:147)
    at com.baosight.bsfc4.mn.lg.utils.Test.main(Test.java:34)

谁能告诉我是什么问题?我的 java 代码有问题吗?

谢谢。

【问题讨论】:

  • 机器是监听指定的IP地址还是只监听本地主机?您应该检查您的 mongDB 配置文件中的“bind_address”。

标签: java mongodb mongodb-java


【解决方案1】:

改用createMongoCredential(),它应该会为您创建正确类型的凭据。

【讨论】:

  • 正如你所说,我使用 MongoCredential.createCredential() 并且它有效。
【解决方案2】:

解决方案:

需要为此用户提供 dbAdmin 角色

db.grantRolesToUser("Username", [{ "role" : "dbAdmin", "db" : "DBName" }])

【讨论】:

    【解决方案3】:

    检查不同类型的方法:http://api.mongodb.com/java/current/com/mongodb/MongoCredential.html

    尝试使用

    createCredential(String userName, String database, char[] password)
    

    代替

    createMongoCRCredential(String userName, String database, char[] password)
    

    后一种使用挑战-响应协议,您的 MongoDB 可能不支持/授权。

    String user="dfasdfgsdfg";
        String database="odhah";
        char[] password="dfgsdfg960".toCharArray();
    
        MongoCredential credential = MongoCredential.createCredential(user,
                database,
                password);
        MongoClient mongoClient = new MongoClient(new ServerAddress("125.025.125.2", 27017),
                Arrays.asList(credential));
    
        MongoDatabase db = mongoClient.getDatabase(database);
        MongoCollection<Document> collection = db.getCollection("names");
        System.out.println("connecting to host....."+mongoClient);
        System.out.println("connecting to database....."+collection);
    
        List<Document> foundDocument = collection.find(new Document("userId","124")).into(new ArrayList<Document>());
        for (int i=0;i<foundDocument.size();i++) {
            System.out.println(">>>"+foundDocument.get(i));
    
        }
    

    【讨论】:

      【解决方案4】:

      完整的代码,考虑到Authentication during connection to MongoDB server instance using Java,是:

          //config is a class populating DB properties and credentials from a properties file
      
        List<ServerAddress> serverAddresses = new ArrayList<>();
          for (String node: config.getNodes()){
              serverAddresses.add( new ServerAddress(node) );
          }
          List<MongoCredential> credentials = new ArrayList<>();
          credentials.add(
                  MongoCredential.createCredential(
                          config.getUser(),
                          config.getDb(),
                          config.getPassword().toCharArray()
                  )
          );
          MongoClient mongo = new MongoClient( serverAddresses, credentials );
          db = mongo.getDatabase("hippo_reporting");
          collection = db.getCollection(config.getCollection());
      // Now, we can do inserts etc...
      

      【讨论】:

        猜你喜欢
        • 2019-06-22
        • 2021-01-18
        • 2015-08-29
        • 2018-11-27
        • 1970-01-01
        • 2018-09-25
        • 2015-07-09
        • 2016-03-20
        • 2010-09-12
        相关资源
        最近更新 更多