Spring Boot项目切换FerretDB替代MongoDB时Testcontainers环境下认证失败问题
我来帮你排查这个认证失败的问题,你遇到的情况是FerretDB虽然兼容MongoDB协议,但底层依赖PostgreSQL,所以认证逻辑和原生MongoDB有不少差异,咱们一步步拆解可能的问题点:
先检查容器的等待条件是否准确
你现在用的是等待pg_cron scheduler started这条日志,但这只是PostgreSQL服务启动完成的信号,FerretDB本身可能还没初始化好,没法正常处理MongoDB的认证请求。你可以把等待条件改成监听FerretDB自己的就绪日志,比如:.waitingFor(Wait.forLogMessage(".*Ferretdb is ready.*", 1))这样能确保FerretDB完全启动就绪后,你的应用再发起连接,避免因为容器未完全初始化导致的“假认证失败”。
明确指定MongoDB驱动的认证机制
FerretDB默认支持SCRAM-SHA-1和SCRAM-SHA-256这两种认证机制,但Java的MongoDB驱动有时候会优先尝试其他不兼容的机制。你可以在连接URI里强制指定认证机制,比如:"mongodb://chairman:password@127.0.0.1:%s/test?authMechanism=SCRAM-SHA-256".formatted(MONGO.getMappedPort(27017))这样能让驱动和FerretDB的认证逻辑对齐,避免机制不匹配导致的失败。
调整认证的源数据库(authSource)
原生MongoDB里很多时候会在admin数据库完成认证,再切换到业务数据库,FerretDB也遵循这个逻辑。你可以试试把URI改成先连接admin数据库认证,再指定业务数据库:"mongodb://chairman:password@127.0.0.1:%s/test?authSource=admin&authMechanism=SCRAM-SHA-256".formatted(MONGO.getMappedPort(27017))这里的
authSource=admin会告诉FerretDB用PostgreSQL的postgres数据库(对应Mongo的admin库)来做认证,这更符合FerretDB的映射逻辑。最后再确认容器环境变量的配置
你设置的POSTGRES_USERNAME和POSTGRES_PASSWORD是给FerretDB自带的PostgreSQL用的,这个没问题,但要注意FerretDB的eval镜像里,这个用户需要有足够的权限来创建和管理schema(FerretDB会把Mongo的数据库映射为PostgreSQL的schema)。如果前面的调整都没用,你可以尝试添加环境变量POSTGRES_DB=test到容器配置里,提前创建好对应的PostgreSQL数据库,确保用户有权限访问。
你可以先从修改等待条件和指定认证机制这两步开始试,这两个是最常见的问题点。
内容来源于stack exchange

