Node.js 中实现 LDAP 客户端查询数据

1,466 阅读2分钟

背景

从 LDAP Server 端获取用户信息进行权限控制。

LDAP 是什么?

轻量目录访问协议,「LDAP 是一个应用协议」,具体参考LDAP 协议入门(轻量目录访问协议)

名词解释

使用 LDAP 协议,需了解 Entry 项、dn、cn、ou、dc 是什么。

Entry 项

在用户目录中,看到的每一行,都可以叫做一项,不论是叶子节点还是中间的节点。项包含一个 DN,一些属性,一些对象类。

image.png

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 官网

  1. 安装 ldapjs
yarn add ldapjs
  1. 实现 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();
        });
      });
    });

参考文档