Ошибка PassportJS: никакие другие операции не могут быть выполнены над соединением, пока привязка прерывается периодически
TLDR: Есть ли проблема с расой в passportjs или passport-ldapauth?
Я использую koa-passport
библиотека сpassport-ldapauth
стратегия в приложении nodejs, предназначенная для аутентификации пользователя по AD (Active Directory). Вау, это был полный рот.
Вот ошибка, от которой я получаю ответpassport.authenticate
я предполагаю, что возвращается из LDAP:
BusyError: 00002024: LdapErr: DSID-0C060810, comment: No other operations may be performed on the connection while a bind is outstanding.
Проблема здесь очевидна, существует невыполненная привязка, и она должна быть закрыта, прежде чем я смогу выполнить другую привязку для аутентификации следующего пользователя. Решение, однако, не так, оно может лежать с LDAP или с passportjs. Я здесь в надежде найти решение для последнего. (Собираемся изучить параметры конфигурации для LDAP, ожидая ответа на этот вопрос#multiprocessing)
Вот мой код:
import passport from 'koa-passport';
import LdapStrategy from 'passport-ldapauth';
import { readFileSync } from 'fs';
const ldapCert = readFileSync(process.env.LDAP_CERT, 'utf8');
const ldapConfig = {
server: {
url: process.env.LDAP_URL,
bindDN: process.env.LDAP_BINDDN,
bindCredentials: process.env.LDAP_PASSWORD,
searchBase: process.env.LDAP_SEARCH_BASE,
searchFilter: process.env.LDAP_SEARCH_FILTER,
searchAttributes: ['sAMAccountName'],
tlsOptions: {
ca: [ldapCert]
}
}
};
module.exports = async (ctx, next) => {
passport.initialize();
passport.use(new LdapStrategy(ldapConfig));
await passport.authenticate('ldapauth', { session: false }, async (err, user, info) => {
if (err) {
console.log('Invalid Authentication Error');
ctx.throw('INVALID_AUTHENTICATION');
} else if (!user) {
console.log('Invalid username or password Error');
ctx.throw('INVALID_USERNAME_PASSWORD');
} else {
await next(); // continue to authorization flow
}
})(ctx, next);
Прежде чем мы начнем, знайте, что всеldapConfigs
остаются неизменными на протяжении всей жизни приложения, что означает, что я используюодно и то же BINDDN и PASSWORD для каждого поиска.
Так как указано в названии, эта ошибка происходит с перебоями. Таким образом, сам код работает в целом, и я могу аутентифицировать пользователей примерно в 95% случаев, и если он когда-нибудь выдаст INVALID_AUTHENTICATION
ошибка, когда пароль был правильным, то есть когда я получаю BusyError
в логах.
Эта проблема более заметна и ее легче воспроизвести, когда я ввожу поддельное имя пользователя / пароль, в идеале мне нужно будет ввести INVALID_USERNAME_PASSWORD
ошибка, которая у меня примерно в 75% случаев. Остальные 25% я получаю INVALID_AUTHENTICATION
,
Я даже пытался воспроизвести его, используя ldapsearch
командный инструмент, в сочетании с tmux
, Я выполнил вызов в ~20 панелях одновременно, используя один и тот же binddn, и они все вернулись просто отлично (я должен попытаться запустить его с большим количеством? 100? 1000?). Это то, что заставило меня поверить, что проблемы были не с LDAP или AD, а с passportjs.
Я пришел к выводу, что, возможно, есть проблема с расой в passportJS, но я не смог найти никакой литературы по паутинам. Кто-нибудь сталкивался с чем-то подобным? Я полагаю, что, возможно, связь не закрывается, потому что иногда passport.authenticate
может вернуться до вызова обратного вызова? Это вообще возможно? Это как-то связано с тем, как я его кодировал с помощью async / await?
Мой запасной вариант - полностью отказаться от passportjs и попробовать с ldapjs. Любые мысли, комментарии, предложения, обсуждения будут оценены
Вот полная трассировка стека, если это необходимо:
BusyError: 00002024: LdapErr: DSID-0C060810, comment: No other operations may be performed on the connection while a bind is outstanding., data 0, v3839
at messageCallback (/app/node_modules/ldapjs/lib/client/client.js:1419:45)
at Parser.onMessage (/app/node_modules/ldapjs/lib/client/client.js:1089:14)
at emitOne (events.js:116:13)
at Parser.emit (events.js:211:7)
at Parser.write (/app/node_modules/ldapjs/lib/messages/parser.js:111:8)
at TLSSocket.onData (/app/node_modules/ldapjs/lib/client/client.js:1076:22)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at TLSSocket.Readable.push (_stream_readable.js:208:10)
at TLSWrap.onread (net.js:597:20)
InternalServerError: INVALID_AUTHENTICATION
at Object.throw (/app/node_modules/koa/lib/context.js:97:11)