项目中需要在mongodb使用用户认证,一是在mongodb开启认证,二是在客户端使用认证
1.开启mongodb
$./mongod --dbpath /usr/local/mongodb/db/database --logpath /usr/local/mongodb/log/log.txt --logappend
2.常规开启mongodb后,使用mongodb的客户端(比如mongobooster)或者shell创建用户
注意,local数据库不能创建用户
use test
db.createUser({
user: "test",
pwd: "1234",
roles: [{role: "readWrite", db: "test" }]
})
3.重启mongodb,以认证方式的启动
$./mongod --dbpath /usr/local/mongodb/db/database --logpath /usr/local/mongodb/log/log.txt --logappend --auth
4.此时客户端已经要求输入用户和密码才能登陆了
使用python快速测试
from pymongo import MongoClient
conn = MongoClient("10.60.38.159",27017)
db = conn.test
db.authenticate("test", "1234")
content = db.user.find()
for i in content:
print i
显示数据查询到的数据
5.使用scala中的reactivemongo连接mongdb
问题来了……
当在scala使用用户认证,查询mongodb时不返回数据
import reactivemongo.api._
import scala.concurrent.ExecutionContext.Implicits.global
import reactivemongo.bson._
import reactivemongo.api.collections.bson.BSONCollection
import reactivemongo.core.nodeset.Authenticate
object test2 {
def main(args: Array[String]) {
val driver = new MongoDriver
val credentials = List(Authenticate("test", "test", "1234"))
val connection = driver.connection(List("10.60.38.159:27017"),authentications = credentials)
val db = connection("test")
val collection:BSONCollection = db("user")
val query = BSONDocument("name"->"Kobe")
collection.find(query).cursor[BSONDocument]().collect[List]().map {
list =>
for(doc <- list){
val id = doc.getAs[BSONObjectID]("_id").getOrElse(BSONObjectID)
val name = doc.getAs[BSONString]("name").getOrElse(BSONString("no name")).value
val address = doc.getAs[BSONString]("address").getOrElse(BSONString("no address")).value
println("_id:"+id+",name:"+name+",address:"+address)
}
}
}
}
得不到结果,且程序不停止。。。
后来查看Mongodb日志发现问题:
2016-11-16T22:45:55.496+0800 I ACCESS [conn178] Failed to authenticate test@test with mechanism MONGODB-CR: AuthenticationFailed: MONGODB-CR credentials missing in the user document
其中一条日志如上,显示认证机制失败。。。
于是笔者翻了下reactivemongo的文档(见http://reactivemongo.org/releases/0.11/documentation/tutorial/connect-database.html)查找authMode关键词,解释如下:
authMode: The authentication mode. By default, it’s the backward compatible MONGODB-CR which is used. If this options is set to scram-sha1, then the SCRAM-SHA-1 authentication will be selected.
reactivemongo的默认认证机制是”MONGODB-CR”,然后我们去mongodb的官网查看得知,Mongodb的默认认证机制是”SCRAM-SHA-1”(见https://docs.mongodb.com/manual/core/security-scram-sha-1/#authentication-scram-sha-1),原因知道了,接下来设定下认证方式就行了。
参考reactivemongo官网文档(http://reactivemongo.org/releases/0.11/documentation/tutorial/connect-database.html)需要设置MongoConnectionOptions,我们进入该类查看得知reactivemongo中authMode默认是”CrAuthentication”,可以设置为”ScramSha1Authentication”(具体参考MongoConnectionOptions类的源码)
最后的scala代码如下:
import reactivemongo.api._
import scala.concurrent.ExecutionContext.Implicits.global
import reactivemongo.bson._
import reactivemongo.api.collections.bson.BSONCollection
import reactivemongo.core.nodeset.Authenticate
object test2 {
def main(args: Array[String]) {
val driver = new MongoDriver
val conOpts = MongoConnectionOptions(authMode=ScramSha1Authentication)
val credentials = List(Authenticate("test", "test", "1234"))
val connection = driver.connection(List("10.60.38.159"),options = conOpts,authentications = credentials)
val db = connection("test")
val collection:BSONCollection = db("user")
val query = BSONDocument("name"->"Kobe")
collection.find(query).cursor[BSONDocument]().collect[List]().map {
list =>
for(doc <- list){
val id = doc.getAs[BSONObjectID]("_id").getOrElse(BSONObjectID)
val name = doc.getAs[BSONString]("name").getOrElse(BSONString("no name")).value
val address = doc.getAs[BSONString]("address").getOrElse(BSONString("no address")).value
println("_id:"+id+",name:"+name+",address:"+address)
}
}
}
}
最后终于显示出结果了