X.509 客户端认证需TLS强制启用、证书合规且用户显式注册三者缺一不可;mongod必须配置--tlsMode requireTLS,客户端证书subject须与$external数据库中创建的用户名完全一致,并包含keyUsage=digitalSignature和extendedKeyUsage=clientAuth扩展。

直接上结论:X.509 客户端认证不是“配个参数就能用”的功能,它依赖 TLS 基础、证书合规性、用户映射三者同时成立;任一环节出错,连接会静默失败或报 No credentials are available in the security package 这类无上下文错误。
必须先启用 requireTLS 模式
mongod 启动时若未强制 TLS,X.509 认证根本不会触发——哪怕客户端带了证书,服务端也会当作普通连接处理。
-
--tlsMode requireTLS是硬性前提,不能设为preferTLS或disabled -
--tlsCertificateKeyFile必须指向包含服务器证书和私钥的 PEM 文件(不能分开) -
--tlsCAFile必须提供根 CA 证书,用于验证客户端证书签名链;若用自签名 CA,该文件就是你签发客户端证书时用的那个 CA PEM - Windows 上若用
--tlsCertificateSelector替代--tlsCertificateKeyFile,需确保证书已导入当前用户证书存储且标记为“可导出”
客户端证书必须满足 subject 和扩展字段要求
常见错误是证书能建 TLS 连接但无法通过身份验证——问题几乎总出在证书本身。
- subject 中的
O(Organization)、OU(Organizational Unit)、DC(Domain Component)三者组合,必须与集群成员证书(如副本集节点间通信用的证书)不同;否则 mongod 会拒绝认证并记录警告 - 证书必须含
keyUsage = digitalSignature和extendedKeyUsage = clientAuth扩展;OpenSSL 生成时漏掉-addext "extendedKeyUsage=clientAuth"就会失败 - 证书 subject 必须与后续要创建的 MongoDB 用户名完全一致,例如
CN=app-client,OU=dev,O=myorg→ 用户名就得是CN=app-client,OU=dev,O=myorg,大小写、空格、逗号都不能差 - 证书不能过期,且 mongod 主机系统时间不能比证书有效期早超过 30 天,否则日志报 warning,部分驱动(如 .NET)会直接拒绝
必须手动把证书 subject 注册为 $external 用户
证书只是“钥匙”,MongoDB 不会自动把它当用户;不显式创建用户,认证必然失败。
- 用
mongoshell 连到 admin 数据库,执行:db.getSiblingDB("$external").createUser({ user: "CN=app-client,OU=dev,O=myorg", roles: [{ role: "readWrite", db: "myapp" }], mechanisms: ["MONGODB-X509"] }) - 用户名长度不能超过 10KB,否则客户端会话和因果一致性功能失效
- 不能复用同一份证书 subject 创建多个用户;每个证书 subject 只能对应一个
$external用户 - 如果用 Atlas,需通过
atlasdatabaseuserCRD 配置,而非直接连 shell;自托管部署才走上述 createUser 流程
.NET/C# 驱动里证书加载最容易踩坑
Windows 下 .NET 驱动对 PKCS#12(.p12)证书的内存加载行为不稳定,这是 2026 年仍存在的实际问题。
- 证书必须转成
.p12格式,PEM 直接传给tlsCertificateKeyFile会静默失败;转换命令:openssl pkcs12 -export -out client.p12 -inkey client.key -in client.pem -passout pass:mypass
-
MongoClientSettings中必须显式设置:settings.SslSettings = new SslSettings { EnabledSslProtocols = SslProtocols.Tls12 };(.NET Framework 4.6+ 默认不启用 TLS 1.2) - 证书密码不能为空字符串;即使 PEM 无密码,
.p12导出时也得设一个(如mypass),并在tlsCertificateKeyFilePassword中填相同值 - 若仍报
No credentials are available in the security package,检查证书是否被 Windows “证书管理器”标记为“不可导出”——必须右键→所有任务→导出→勾选“如果可能,则导出私钥”
最常被忽略的是:证书 subject 和 $external 用户名的字符级一致性,以及 .p12 导出时私钥导出权限的设置。这两点不验证,其他步骤全对也连不上。


















