MongoDB Java驱动升级4.6.1后find查询报error code13 Unauthorized
问题根因
- 首先要明确:4.x版本MongoDB驱动是懒认证模式,启动日志里的连接成功只代表TCP三次握手完成,创建
MongoClient实例时不会做身份校验,第一次执行增删改查命令时才会真正触发认证和权限校验,所以启动阶段的正常日志完全不能代表认证配置正确。 - 认证源配置缺失:旧版3.x驱动里你通过
MongoCredential.createCredential的第二个参数显式指定了认证库为admin——也就是你的数据库账号是创建在admin库下的。但新版代码里用的连接串没有加authSource参数,驱动没法正确找到用户凭证存储的位置,认证流程就会出错。 - 操作的数据库不匹配:旧版代码里
morphia.createDatastore(mongoClient, "mycollection")的第二个参数是数据库名,也就是说旧版本实际操作的业务库是mycollection,只是用admin库下的账号做认证,你的账号本身只有mycollection库的操作权限,没有admin库的权限;但新版代码里你写了getDatabase("admin"),直接往admin库发查询命令,自然会报无权限错误。
修复方法
根据你实际的数据存储位置选对应方案即可:
如果你确认mycollection集合确实存在于admin库下
只需要修改连接串,显式指定认证源和默认操作库即可:
mongodb://<username>:<password>@<mongodb_server_address>:27017/admin?authSource=admin
连接串里/admin代表默认操作的数据库是admin,authSource=admin告诉驱动去admin库下查找用户凭证做认证。
如果你要和旧版本逻辑完全对齐(旧版本实际操作的是mycollection库)
需要改两处:
- 修改连接串,指定认证源为admin,默认操作库为mycollection:
mongodb://<username>:<password>@<mongodb_server_address>:27017/mycollection?authSource=admin - 修正获取集合的代码,不要连admin库,改为连业务库mycollection,同时建议显式给
MongoCollection指定泛型类型,避免后续类型转换问题:CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build(); CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries( MongoClientSettings.getDefaultCodecRegistry(), CodecRegistries.fromProviders(pojoCodecProvider) ); MongoClient client = MongoClients.create(uri); MongoCollection<MyEntity> collection = client.getDatabase("mycollection") .withCodecRegistry(pojoCodecRegistry) .getCollection("mycollection", MyEntity.class);
改完之后再执行查询就不会有权限报错了。
内容的提问来源于stack exchange,提问作者Ousmane MBINTE
相关产品推荐
相关产品推荐

