java在访问mongodb的过程中,经常会遇到授权错误之类的报错。通常的原因包括:
1. mongodb的uri错误
2. mongodb开启了authentication验证(这时候就需要用户名和密码)
然而还存在另一种原因是:uri中没有包含数据库名。
mongodb的url的一般格式可以写为:
String uri ="mongodb://username:password@127.0.0.1:27017/test"
其中username和password为用户名和密码,127.0.0.1是host ip,27017是端口号port,test为要访问的数据库名。mongodb比较特殊,其对于不同的数据库可以设置不同的用户名和密码,因此此处的用户名和密码必须要和数据库名对应。且需要特别指出的是mongodb uri必须要包含数据库名,否则容易出现问题。
通常我们习惯使用驱动程序mongodb-java-driver.jar来完成对mongodb的访问,目前官方推荐使用的方法是MongoClientURI。相关业务代码为:
MongoClientURI mongoClientUri =new MongoClientURI(mongo_uri);
MongoClient mongoclient =new MongoClient(mongoClientUri);
MongoCollection collection = mongoclient.getDatabase(dbName).getCollection(collectionName);
doc_count = collection.count();
MongoClientURI访问mongodb的授权报错
在使用MongoClientURI访问mongodb时需要格外注意的是:uri必须包含数据库名,否则容易出现以下报错:
2018-10-09 13:40:24,008 [.1:27017] INFO (db.driver.cluster: 76) - Exception in monitor thread while connecting to server 127.0.0.1:27017
com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=null, userName='username', source='admin', password=<hidden>, mechanismProperties={}}
at com.mongodb.connection.SaslAuthenticator.wrapInMongoSecurityException(SaslAuthenticator.java:157)
at com.mongodb.connection.SaslAuthenticator.access$200(SaslAuthenticator.java:37)
at com.mongodb.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:66)
at com.mongodb.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:44)
at com.mongodb.connection.SaslAuthenticator.doAsSubject(SaslAuthenticator.java:162)
at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:44)
at com.mongodb.connection.DefaultAuthenticator.authenticate(DefaultAuthenticator.java:32)
at com.mongodb.connection.InternalStreamConnectionInitializer.authenticateAll(InternalStreamConnectionInitializer.java:109)
at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:46)
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:116)
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:113)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.mongodb.MongoCommandException: Command failed with error 18: 'Authentication failed.' on server 127.0.0.1:27017. The full response is { "ok" : 0.0, "errmsg" : "Authentication failed.", "code" : 18, "codeName" : "AuthenticationFailed" }
at com.mongodb.connection.CommandHelper.createCommandFailureException(CommandHelper.java:170)
at com.mongodb.connection.CommandHelper.receiveCommandResult(CommandHelper.java:123)
at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32)
at com.mongodb.connection.SaslAuthenticator.sendSaslStart(SaslAuthenticator.java:117)
at com.mongodb.connection.SaslAuthenticator.access$000(SaslAuthenticator.java:37)
at com.mongodb.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:50)
... 9 more
原因分析:
经过排查确认用户名和密码以及ip都正确,只是mongo_uri中不包括数据库名,即:
String mongo_uri ="mongodb://username:password@127.0.0.1:27017/"
那么为什么会这样呢?原因如下:

从上图中的红框中可以看出,如果mongodb uri中不指定数据库名,那么会默认为admin这个数据库。然而mongo_uri中的username和password并不是admin的,因此会出现授权错误。如果特殊情况即访问的数据库为admin,则即使uri中不指定数据库名也不会出现授权错误。
解决方法:
1. mongo的jdbc url需要包含database的schema名,即:
String mongo_uri ="mongodb://username:password@127.0.0.1:27017/dbname"
其中dbname为数据库名
网友评论