ldap组映射需在admin库显式创建同名角色并绑定权限,否则即使ldap认证成功用户仍无权;authz.querytemplate决定组查询逻辑,bind用户须有足够权限读取用户和组条目。

LDAP组映射必须在admin数据库中显式创建对应角色
LDAP本身不直接赋予MongoDB权限,它只提供用户所属的组DN(如cn=devs,ou=groups,dc=example,dc=com)。MongoDB需要你手动在admin库中创建一个同名(或按authz.queryTemplate匹配出的名称)的角色,并绑定实际权限。没这步,即使LDAP返回了组,用户登录后仍是无权状态。
常见错误现象:Successfully authenticated via LDAP 日志出现,但执行db.runCommand({connectionStatus: 1})发现roles数组为空;或执行任何操作都报not authorized on X to execute Y。
- 角色名必须与LDAP返回的组名**完全一致**(默认按CN解析,大小写敏感)
- 角色必须在
admin数据库中创建,不能在其他库 - 若
authz.queryTemplate返回的是完整DN(如cn=admins,dc=example,dc=com),则角色名就得是这个完整字符串,而非仅admins - 创建时可继承内置角色,例如:
db.createRole({role: "devs", privileges: [], roles: [{role: "readWrite", db: "appdb"}]})
authz.queryTemplate决定LDAP组查询逻辑和返回字段
这个模板不是“查用户属于哪些组”,而是“根据当前用户DN,反向查哪些组包含该用户”。它的语法直接影响你能拿到什么组、能否匹配上角色名。
典型错误配置:authz.queryTemplate: "ou=groups,dc=example,dc=com?memberUid?sub?(memberUid={USER})" —— 这在OpenLDAP中可能有效,但在Active Directory里memberUid根本不存在,应改用member且传入用户完整DN。
- AD环境常用模板:
dc=example,dc=com?cn?sub?(member={USERDN}),其中{USERDN}会被自动替换成用户绑定成功后的DN - OpenLDAP常用模板:
ou=groups,dc=example,dc=com?cn?sub?(memberUid={USER}),注意{USER}是用户名(如alice),非DN - 模板中问号分隔的三段依次是:base DN、返回属性、scope、filter —— 少一段或顺序错会导致查询无声失败
- 可用
mongoldap --config /etc/mongod.conf --user alice --password xxx验证模板是否真能返回预期组名
bind凭据必须有足够权限读取用户和组条目
LDAP bind用户不是“登录用户”,而是MongoDB服务端用来代表自己去查LDAP的“代理账号”。它需要能:① 根据userSearchBase查到目标用户DN;② 根据groupSearchBase和queryTemplate查到该用户的所属组。
最容易被忽略的坑:bind用户在AD里默认没有读取member属性的权限,尤其当组是嵌套或跨OU时。现象是mongoldap报告“LDAP search returned no entries”,但用ldapsearch手工查却能看到组。
- bind用户至少需具备
Read权限于userSearchBase和groupSearchBase两个OU - 在AD中,需显式授予bind用户对
member、memberOf、cn等属性的“Read”权限(通过ADSIEDIT.msc或PowerShell) - 避免使用
Administrator账户做bind —— 权限过大且违反最小权限原则;建议新建专用service account并加进Account Operators组即可 - 密码硬编码在配置里不安全,生产环境应使用
bind.method: "sasl"配合saslauthd或Kerberos
启用了LDAP授权就别依赖本地用户角色
一旦配置了security.ldap.authz.enabled: true,MongoDB会完全跳过system.users里的角色继承逻辑。此时即使你在admin库里给用户alice手动assign了root角色,只要她通过LDAP登录,最终生效的只有LDAP组映射出来的那些角色。
典型误操作:测试时用mongosh -u alice -p --authenticationDatabase admin连上后,发现db.runCommand({connectionStatus: 1})显示的角色跟预期不符 —— 很可能是因为alice同时存在于本地system.users和LDAP中,而MongoDB优先走了LDAP路径,但LDAP组没映射对。
- 调试时先确认连接是否真走LDAP:
db.runCommand({getCmdLineOpts: 1})看输出里是否有"ldap"相关字段 - 用
mongoldap单独验证授权流程,比反复重启mongod快得多 - 如果需要混合模式(部分用户LDAP、部分本地),只能靠应用层路由,MongoDB自身不支持按用户来源分流授权逻辑
admin库找同名角色 → 加载该角色定义的权限。中间任何一环名字不严丝合缝、权限不到位、配置没重载,都会静默失败。最省时间的做法,是把mongoldap当成单元测试工具,每次改完queryTemplate或bind参数都跑一遍。











