背景
从 LDAP Server 端获取用户信息进行权限控制。
LDAP 是什么?
轻量目录访问协议,「LDAP 是一个应用协议」,具体参考LDAP 协议入门(轻量目录访问协议)。
名词解释
使用 LDAP 协议,需了解 Entry 项、dn、cn、ou、dc 是什么。
Entry 项
在用户目录中,看到的每一行,都可以叫做一项,不论是叶子节点还是中间的节点。项包含一个 DN,一些属性,一些对象类。
dn
分辨名,用于标识一个「项」,以及在目录信息树中的位置,可以和文件系统中文件路径类比。dn 字符串从左向右,各组成部分依次向树根靠近。上图中 dn:
dn: uid=einstein,dc=example,dc=com
dc
域名组成,将 example.com 这样的域名,拆成 dc=example,dc=com 这样的形式
ou
组织单元、部门,在 dn 中可能会包含 ou=某某部门 这样的组成部分,这里的 ou 指代组织单元
cn
LDAP 账号
Node.js 中实现 LDAP 客户端
使用 ldapjs 框架,一个用于在 Node.js 中实现 LDAP 客户端和服务端的 js 框架,ldapjs 官网 。
- 安装 ldapjs
yarn add ldapjs
- 实现 LDAP 客户端
const ldap = require('ldapjs');
const config = {
ldapURL: 'ldap://xxxx', // LDAP 服务器地址,加不加端口号以实际为准,我的项目中加端口号无法连接
adminDN: 'CN=,DC=example,DC=com', // 用户信息,必须是从根节点到用户节点的全路径,有可能有 OU、UID
adminPwd: 'xxx', // 用户密码
searchDn: 'DC=example,DC=com', // 查询基础路径,代表查询用户信息在这个路径下进行,由根节点开始
};
// 创建客户端
const ldapClient = ldap.createClient({
url: config.ldapURL,
});
// 监听 error 事件
ldapClient.on('error', err => {
console.log('ldap error', err);
});
// 监听 connect 事件
ldapClient.on('connect', () => {
console.log('ldap connect');
});
// 将 client 绑定 LDAP Server
ldapClient.bind(config.adminDN, config.adminPwd, (bindErr, bindRes) => {
// 查询配置
const opts = {
filter: `username=${username}`, // 查询条件过滤器,查询 username 为 xx 的数据
scope: 'sub', // 查询范围
timeLimit: 500, // 查询超时
attributes: ['username', 'org'] // 选择返回的数据属性
};
// 处理查询事件
ldapClient.search(config.searchDn, opts, (searchErr, searchRes) => {
// 监听查询结果事件
searchRes.on('searchEntry', entry => {
// 获取查询的对象
const user = entry.object;
console.log('查询结果:', user);
});
// 监听查询错误事件
searchRes.on('error', error => {
ldapClient.unbind();
console.log('查询失败:', error);
});
// 监听查询结束事件
searchRes.on('end', result => {
ldapClient.unbind();
});
});
});