如何确保LDAP安全连接并正确写入AD的unicodePwd属性?
LDAP连接与unicodePwd写入问题
环境信息
- 开发环境:Vagrant虚拟机(Ubuntu 24.04 Noble)
- 技术栈:Node.js 20.18.0 + NestJS 10.4.5
- 使用库:ldapts
- 目标:连接安全LDAP服务器,写入AD的unicodePwd字段
背景要求
根据微软官方文档,写入unicodePwd属性需满足:
- 密码需用双引号包裹并以UTF-16编码
- 操作必须在安全连接中执行
初始连接代码及错误
初始代码尝试通过startTLS建立安全连接:
const client = new Client({ url: 'ldaps://<ldapip>', timeout: 0, connectTimeout: 0, }); const bindDN = 'CN=Administrator,CN=Users,DC=myproject,DC=local'; const password = 'mypdw'; try { console.log('D1'); let cert = fs.readFileSync('/vagrant/backend/certs/mycert.crt'); console.log(cert.toString('base64')); await client.startTLS({ ca: [cert], }); console.log('D2'); await client.bind(bindDN, password); console.log('D3'); (...) } catch (error) { return { status: 500, msg: 'LDAP fail', error } } finally { await client.unbind(); }
运行后仅打印D1和证书内容,无法到达D2,报错:
{"code":"UNABLE_TO_VERIFY_LEAF_SIGNATURE"}
已确认证书由AD的CA签发,且已导入Chromium,但合并用户证书与CA证书后问题仍未解决。
修改后的代码及新问题
调整代码后可以连接LDAP,但写入unicodePwd时触发UnwillingToPerformError,不确定是否建立了有效安全连接:
// 试过同时用CA证书和客户端证书,结果一致 let cert = fs.readFileSync('/vagrant/backend/certs/client-cert.crt'); let opts = { ca: [cert], host: 'myurl.myproject.local', rejectUnauthorized: false, secure: true }; const client = new Client({ url: 'ldaps://myurl.myproject.local:636', timeout: 0, tlsOptions: { ...opts, minVersion: 'TLSv1.1' }, connectTimeout: 0, }); const bindDN = 'CN=Administrator,CN=Users,DC=myproject,DC=local'; const password = 'mypdw'; try { console.log('D1'); console.log(cert.toString('base64')); console.log('D2'); await client.bind(bindDN, password); console.log('D3', client.isConnected); let passwdUtf16 = this.encodePassword("mypwd"); var newUser = { sn: 'teste', objectClass: ["organizationalPerson", "person", "user"], unicodePwd: passwdUtf16 } await client.add('cn=test,ou=MyCompany,ou=Organizations,dc=myproject,dc=local', newUser); console.log('D4'); }
也尝试过先添加不含unicodePwd的用户,再执行修改操作:
let change = new Change({ operation: 'replace', modification: new Attribute({ type: 'unicodePwd;binary', values: [passwdUtf16] }) }); await client.modify('cn=test,ou=MyCompany,ou=Organizations,dc=myproject,dc=local', change);
两种方式均触发UnwillingToPerformError,怀疑安全连接未正确建立。
密码编码函数
当前使用的密码编码函数:
encodePassword(str) { const text = '"' + str + '"'; let byteArray = new Uint8Array(text.length * 2); for (let i = 0; i < text.length; i++) { byteArray[i * 2] = text.charCodeAt(i); // & 0xff; byteArray[i * 2 + 1] = text.charCodeAt(i) >> 8; // & 0xff; } return String.fromCharCode.apply(String, byteArray); }
问题
- 如何确认已建立可写入unicodePwd的安全连接?
- 我的密码写入操作是否存在错误?
内容的提问来源于stack exchange,提问作者Nelson Teixeira
相关产品推荐
相关产品推荐

