如何编写搜索过滤器以在LDAP中搜索手机号码或电话号码?

时间:2014-09-03 10:40:23

标签: node.js ldap

我想使用搜索过滤器查询LDAP。为了连接到LDAP服务器,我使用node.js。

我可以使用搜索过滤器在LDAP中搜索任何名称。但是,当我尝试搜索任何手机号码或电话号码时,我收到错误:request timeout (client interrupt)

以下是我搜索名称时使用的node.js代码:

var ldap = require('ldapjs');
var sys   = require('sys');
var assert   = require('assert-plus');

var username = 'XXXXXXX';
var password = 'XXXXXXX';
var domain = "cts.com";
var searchBase = 'dc=cts,dc=com';


var client = ldap.createClient({
    url: 'ldap://myipaddress:portnumber',
    bindDN: "cts.com",
    timeout: 5000,
    connectTimeout: 10000
});

client.bind('cts\\'+username, password, function (err) {
    if (err) {
        console.log(err);
        client.unbind(function (err) {
            console.log('3');
            if (!err) {
                console.log('successfully unbind');
            }
            else {
                console.log(err);
            }
        });
    } else {
        console.log('authenticated');
        var searchResult = search();
    }
});

function search(){
    var opts = {
        filter:'(sAMAccountName='+username+')',
        scope: 'sub',
        attributes: ['sAMAccountName','name','givenName','distinguishedName','displayName','cn','sn',
                    'mail','title','description','department','company','manager',
                    'telephoneNumber','mobile','co','c','l','st','postalCode'],
    };

    client.search(searchBase, opts, function(err, res) {
        assert.ifError(err);

        res.on('searchEntry', function(entry) {
            console.log('searchEntry');
            var user = entry.object;
            console.log(user.objectGUID);
            if(entry.object){
                console.log('entry: %j ' + JSON.stringify(entry.object))
            }
        });
        res.on('searchReference', function(referral) {
            console.log('searchReference');
            console.log('referral: ' + referral.uris.join());
        });
        res.on('error', function(err) {
            console.error('error: ' + err.message);
        });
        res.on('end', function(result) {
            console.log('status: ' + result.status);
            return result;      
        });
    });
}

在命令提示符下运行上述代码后得到的结果是:

authenticated
undefined
searchEntry
undefined

entry: %j {"dn":"CN=anyname,OU=Users,OU=DLF,OU=Chennai,OU=India,OU=APAC,OU=mycompanyname,DC=cts,DC=com","controls":[],"cn":"name","sn":"K-5","c":"IN","l":"C
    hennai","st":"TN","title":"Developer","description":"Associate","postalCode":"600089","telephoneNumber":"123455","givenName":"XXXXXXXXX","distinguis
    hedName":"CN=XXXXXXXX,OU=Users,OU=DLF,OU=Chennai,OU=India,OU=APAC,OU=Cognizant,DC=cts,DC=com","displayName":"XXXXXXXX","co":"IND","department":"Mobility-MM","company":"Any Company Name","name":"anyname","sAMAccountName":"employeeID","mail":"mailid@gmail.com","mobile":"999-091-3918"
}

接下来,我需要在LDAP中搜索字段" mobile"。所以我做的是,我将搜索过滤器重写为

var searchNumber = '999-091-3918';

var opts = {
        filter:'(mobile='+searchNumber+')',
        scope: 'sub',
        attributes: ['sAMAccountName','name','givenName','distinguishedName','displayName','cn','sn',
                    'mail','title','description','department','company','manager',
                    'telephoneNumber','mobile','co','c','l','st','postalCode'],
    };

并运行代码。

这次我得error request timeout (client interrupt)。任何人都可以帮我如何在LDAP中编写移动电话和电话号码的搜索过滤器吗?

1 个答案:

答案 0 :(得分:0)

您必须在LDAP过滤字符串中转义搜索值,因为()等字符具有特殊含义,并且在未转义时会中断过滤器。

LDAP过滤字符串的字符转义模式为"\"和字符的十六进制代码。 "("将是"\28"

另见http://msdn.microsoft.com/en-us/library/aa746475.aspx,"特殊字符"

所以你的过滤器应该是(当然这适用于所有其他领域,如" name"以及):

var opts = {
        filter:'(mobile=' + ldapFilterEscape(searchNumber) + ')',
        // etc, etc
    };

其中ldapFilterEscape

function ldapFilterEscape(str) {
    return str.replace(/[*()\\\/]/g, function ($0) {
        return "\\" + $0.charCodeAt(0).toString(16);
    });
}