[英]Node JS LDAP Auth User
我正在創建一個登錄身份驗證頁面,用戶將在其中輸入活動目錄用戶名和密碼,並使用NodeJS我會檢查它是否有效,但我一直在
[Error: LDAP Error Bad search filter]
要么
[Error: Search returned != 1 results]
當我嘗試搜索用戶名和密碼時,我的代碼如下:
我正在使用: https : //github.com/jeremycx/node-LDAP ,假設用戶輸入了hhill的用戶名
var ldap = require('LDAP');
var ldapServer = new ldap({ uri: 'ldap://batman.lan', version: 3});
ldapServer.open(function(error) {
if(error) {
throw new Error('Cant not connect');
} else {
console.log('---- connected to ldap ----');
username = '(cn='+username+')';
ldapServer.findandbind({
base: 'ou=users,ou=compton,dc=batman,dc=lan',
filter: username,
password: password
}, function(error, data) {
if(error){
console.log(error);
} else {
console.log('---- verified user ----');
}
});
}
});
有沒有人對我做錯了什么有任何建議?
UPDATE
以下是我提出的解決方案,如果有人需要它,請在下面的答案的幫助下
var username = request.param('username');
var password = request.param('password');
var ldap = require('ldapjs');
ldap.Attribute.settings.guid_format = ldap.GUID_FORMAT_B;
var client = ldap.createClient({
url: 'ldap://batman.com/cn='+username+', ou=users, ou=compton, dc=batman, dc=com',
timeout: 5000,
connectTimeout: 10000
});
var opts = {
filter: '(&(objectclass=user)(samaccountname='+username+'))',
scope: 'sub',
attributes: ['objectGUID']
};
console.log('--- going to try to connect user ---');
try {
client.bind(username, password, function (error) {
if(error){
console.log(error.message);
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
} else {
console.log('connected');
client.search('ou=users, ou=compton, dc=batman, dc=com', opts, function(error, search) {
console.log('Searching.....');
search.on('searchEntry', function(entry) {
if(entry.object){
console.log('entry: %j ' + JSON.stringify(entry.object));
}
});
search.on('error', function(error) {
console.error('error: ' + error.message);
});
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
});
}
});
} catch(error){
console.log(error);
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
}
在這種情況下,您需要ldapClient
而不是ldapServer
,這是來自官方文檔的示例代碼:
var ldap = require('ldapjs');
ldap.Attribute.settings.guid_format = ldap.GUID_FORMAT_B;
var client = ldap.createClient({
url: 'ldap://127.0.0.1/CN=test,OU=Development,DC=Home'
});
var opts = {
filter: '(objectclass=user)',
scope: 'sub',
attributes: ['objectGUID']
};
client.bind('username', 'password', function (err) {
client.search('CN=test,OU=Development,DC=Home', opts, function (err, search) {
search.on('searchEntry', function (entry) {
var user = entry.object;
console.log(user.objectGUID);
});
});
});
@Sukh感謝您發布UPDATE解決方案; 但是,您在UPDATE中發布的代碼存在問題。 雖然它適用於簡單的情況,但對於較大的查詢,您會發現在輸出結果之前您已取消綁定。 我的解決方案是將你的unbinds移動到search.on函數中。
這是您的更新的編輯:
var ldap = require('ldapjs');
ldap.Attribute.settings.guid_format = ldap.GUID_FORMAT_B;
var client = ldap.createClient({
url: 'ldap://batman.com/cn='+username+', ou=users, ou=compton, dc=batman, dc=com',
timeout: 5000,
connectTimeout: 10000
});
var opts = {
filter: '(&(objectclass=user)(samaccountname='+username+'))',
scope: 'sub',
//attributes: ['objectGUID']
// This attribute list is what broke your solution
attributes: ['objectGUID','sAMAccountName','cn','mail','manager','memberOf']
};
console.log('--- going to try to connect user ---');
try {
client.bind(username, password, function (error) {
if(error){
console.log(error.message);
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
} else {
console.log('connected');
client.search('ou=users, ou=compton, dc=batman, dc=com', opts, function(error, search) {
console.log('Searching.....');
search.on('searchEntry', function(entry) {
if(entry.object){
console.log('entry: %j ' + JSON.stringify(entry.object));
}
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
});
search.on('error', function(error) {
console.error('error: ' + error.message);
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
});
// don't do this here
//client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
});
}
});
} catch(error){
console.log(error);
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
}
至少這是我在使用Active Directory搜索解決方案時發現的。 memberOf在我的用例中返回了很多條目,並且unbinds過早地完成了,所以我收到以下錯誤:
error: 1__ldap://my.domain.com/,OU=Employees,OU=Accounts,DC=my,DC=domain,DC=com closed
client disconnected
建議
1.不要使用ldapauth-fork(巨大的懸掛問題,如果我們遇到多個請求,那么在一段時間后庫沒有響應並且不返回任何內容。)
2.不要使用passport-ldapauth(內部調用ldapauth-fork)
我們可以使用ldapjs,它易於實現並基於事件驅動方法。
nodejs代碼下面解釋了ldap auth和search的完整解決方案。
JS代碼
const ldap = require('ldapjs');
let client
// unbind after completion of process
function closeConnection() {
console.log('closeConnection')
client.unbind(err => {
console.log('unbind error', err)
});
}
function search() {
const searchOptions = {
filter: '(uid=yourSearchText)', // search text
scope: 'sub'
};
return new Promise((resolve, reject) => {
client.search('ou=consultants,' + 'ou="Your OU",ou=yourOu,dc=yourDc,dc=com', searchOptions, (err, res) => {
res.on('searchEntry', entry => {
console.log('searchEntry', entry.object);
resolve(entry.object)
});
res.on('searchReference', referral => {
console.log('referral: ' + referral.uris.join());
resolve(referral.uris.join())
});
res.on('error', err => {
console.error('search error: ' + err.message);
reject(err)
});
res.on('end', result => {
console.log('If not found', result);
reject({ message:'User not found'})
});
});
})
}
function authenticate() {
const server = 'ldap server ip';
client = ldap.createClient({
url: `ldap://${server}`
});
return new Promise((resolve, reject) => {
client.bind('cn=yourcn,dc=yourdc,dc=com', 'sortedSolutions', err => {
if (err) {
reject(err)
}
resolve('Authenticated successfully')
});
})
}
function start(req, res) {
let searchResponseData
authenticate()
.then(authenticateResponse => {
console.log('authenticateResponse', authenticateResponse)
return search()
})
.then(searchResponse => {
console.log('searchResponsesearchResponse', searchResponse)
searchResponseData = searchResponse
return closeConnection()
})
.then(closeConnectionResponse => {
console.log('ldap connection closed', closeConnectionResponse)
res.status(200).send(searchResponseData)
})
.catch(error => {
console.log('catch error', error)
res.status(400).send(error)
})
}
module.exports.start = start
//我們可以使用相同的代碼而不進行身份驗證,只需將''傳遞給綁定函數client.bind('','',err => {//與上面相同})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.