LDAP授权查询与认证查询相互独立,必须显式配置ldap.authz.queryTemplate和ldap.authz.mode=authz才能启用;角色名须与LDAP返回值严格一致(大小写、格式、转义均敏感),否则授权失败。

LDAP授权查询和认证查询不是一回事
很多人以为开了LDAP认证(ldapAuthz 或 ldapBind)就自动能做授权查询,其实不是。MongoDB的LDAP支持分两块:认证(Authentication)靠 ldapBind,授权(Authorization)靠独立的 ldapAuthz 查询机制,必须显式启用并配置,否则 $external 用户即使登录成功,也拿不到角色信息。
必须配置 ldap.authz.queryTemplate
这是开启LDAP授权查询最关键的一步。没有它,MongoDB压根不会去查LDAP获取用户角色。模板里用 {USER} 占位符代入用户名,返回的LDAP条目必须包含角色名(如 cn 或自定义属性),且该属性值需与MongoDB中定义的角色名完全一致。
常见错误现象:Unauthorized: not authorized on admin to execute command { getRole: "xxx", ... } 或登录后执行命令直接报 not authorized,但日志里看不到LDAP查询请求——基本就是这个模板没配或格式错。
-
ldap.authz.queryTemplate值必须是合法LDAP搜索过滤器,例如:(memberUid={USER})或(uid={USER})(objectClass=posixGroup) - 模板中不能有空格、换行或未转义的特殊字符(如
()=都要原样保留) - 如果LDAP服务器不支持嵌套组解析,就别指望
memberOf属性自动展开;得确保查询结果直出角色名
需要同时开启 ldap.authz.mode 并设为 authz
仅配 queryTemplate 不够,还得告诉MongoDB“我要走授权查询流程”。ldap.authz.mode 有两个可选值:none(默认,关掉授权查询)、authz(启用)。设成 authz 后,每次用户执行操作前,MongoDB会按模板发起一次LDAP查询,把返回的DN或属性映射成本地角色。
性能影响明显:每次权限校验都多一次网络请求,高并发下容易拖慢响应。如果LDAP服务器响应慢或不稳定,建议加缓存(MongoDB本身不缓存LDAP授权结果,得靠外部方案如SSSD或中间代理)。
- 配置方式:启动时加
--ldapAuthzMode authz,或在mongod.conf中写:security:<br> ldap:<br> authz:<br> mode: authz<br> queryTemplate: "(memberUid={USER})" - 不支持
authz模式的老版本(如 4.2 之前)会静默忽略该配置,务必确认版本兼容性 - 启用后,
db.runCommand({getRole: "xxx", db: "admin"})查到的角色来源会标为"roleSource" : "$external",而不是"admin"
角色名必须严格匹配LDAP返回值
MongoDB不会做任何字符串归一化处理。如果LDAP返回的是 readWrite@myapp,而你在MongoDB里用 db.createRole 定义的是 readWrite_myapp,那授权就失败——哪怕语义一样也不认。
最容易被忽略的一点:大小写敏感。LDAP里返回 ReadOnly,但MongoDB角色叫 readonly?不行。必须一字不差。
- 调试时用
ldapsearch手动跑一遍queryTemplate,确认返回的属性值(比如cn)是否就是你期望的角色名 - 如果LDAP里角色存在多个属性(如
cn、ou、description),得在ldap.authz.queryTemplate里明确指定哪个字段对应角色,MongoDB只认第一个匹配项 - 不要依赖
memberOf的DN路径自动截取角色名;它返回的是完整DN,不是角色标识符
实际部署时,最常卡住的地方不是配置语法,而是LDAP服务端返回的数据结构和MongoDB期待的不一致——得先看清它吐什么,再决定模板怎么写,而不是反过来。










