Ошибка аутентификации LDAP с использованием passport-ldapauth на Node.js - PullRequest
1 голос
/ 03 октября 2019

Привет, я новичок в openldap и nodejs. Я пытаюсь создать аутентификацию openldap и использовать простое приложение для проверки узлов на локальном сервере ldap.

Насколько я понимаю, я могу создать сервер ldap и добавить всех пользователей в Apache Directory Studio. Затем напишите простое приложение для узла с той же конфигурацией, что и для сервера ldap. Использование почтальона для отправки запросов на аутентификацию, и я должен быть в состоянии получить авторизованные результаты. Пожалуйста поправьте меня, если я ошибаюсь.

Ниже приведены шаги, которые я предпринял:

  1. Я использовал Apache Directory Studio для локальной настройки ldap-сервера.

  2. Затем я попытался настроить простое приложение nodejs (код показан ниже).

  3. Когда я использовал Postman, чтобы отправить запрос аутентификации какому-либо пользователю, который я настроил ранее с помощью Apache Directory Studio, но я продолжал получать сообщение об ошибке Unauthorized.

  4. Я верю, что могу поразить приложение узла своими вызовами почтальона, потому что я могу получить этот "Несанкционированный" ответ с именем пользователя ипароль, который существует в Apache Studio. Но приложение узла не работает с / не подключено к серверу Ldap, настроенному Apache Directory Studio, потому что я могу изменить поля сервера в коде узла так, чтобы они полностью отличались от сервера ldap, но все еще могли получать неавторизованный ответ в почтальоне. ,У меня, вероятно, нет полного понимания серверов ldap, и, возможно, приложение узла и сервер ldap полностью отделены как есть? Или это должно работать, это просто что-то не так с моим кодом?

Ниже приведен мой самый последний код:

var express      = require('express'),
    passport     = require('passport'),
    bodyParser   = require('body-parser'),
    LdapStrategy = require('passport-ldapauth'),
    basicAuth = require('basic-auth')

var OPTS = {
  server: {
    url: 'ldap://localhost:389',
    bindDN: 'cn=admin,ou=users,dc=contoso,dc=com',
    bindCredentials: 'P@ss1W0Rd!',
    searchBase: 'ou=users,dc=contoso,dc=com',
    searchFilter: '(uid={{Username}})'
  },
  credentialsLookup: basicAuth
  // ,
  // usernameField: user,
  // passwordField: pass
};

var app = express();

passport.use(new LdapStrategy(OPTS));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(passport.initialize());

app.post('/login', passport.authenticate('ldapauth', {session: false}), function(req, res) {
  res.send({status: 'ok'});
});

app.listen(8080);


Вот пользователь, которого я пытался аутентифицировать:


dn: cn=Aaron Painter,ou=users,dc=contoso,dc=com
objectClass: top
objectClass: posixAccount
objectClass: organizationalPerson
objectClass: person
objectClass: inetOrgPerson
cn: Aaron Painter
gidNumber: 70051
homeDirectory: /home/aaronp
sn: Painter
uid: aaronp
uidNumber: 70050
displayName: Aaron Painter
givenName: Aaron
mail: aaronp@contoso.com
manager: cn=Christine Koch,ou=users,dc=contoso,dc=com
telephoneNumber: (212) 555-8335
title: Strategy Consulting Manager
userPassword: AAA

Вот звонок почтальона, который я использовал: звонок почтальона

Вот журнал, показанный на сервере:

contosoOpenLdap | 5d9b8107 conn=1062 fd=19 ACCEPT from IP=172.17.0.1:47712 (IP=0.0.0.0:389)
contosoOpenLdap | 5d9b8107 conn=1063 fd=20 ACCEPT from IP=172.17.0.1:47714 (IP=0.0.0.0:389)
contosoOpenLdap | 5d9b8107 conn=1063 op=0 BIND dn="cn=admin,ou=users,dc=contoso,dc=com" method=128
contosoOpenLdap | 5d9b8107 conn=1063 op=0 RESULT tag=97 err=49 text=
contosoOpenLdap | 5d9b8107 conn=1063 op=1 UNBIND
contosoOpenLdap | 5d9b8107 conn=1063 fd=20 closed

Код ошибки49 означает, что есть неверный DN или пароль. Но конфиг мне кажется правильным.

Пожалуйста, помогите.

1 Ответ

0 голосов
/ 03 октября 2019

Необходимо исправить три вещи (при условии, что ваши учетные данные верны):

  • Неправильный синтаксис поискового фильтра, в нем не следует вводить пароль
  • Использованиеполный dn для searchBase (не rdn)
  • Либо вы получаете учетные данные из запроса через credentialsLookup, либо вы устанавливаете usernameField и passwordField.

Например, сохраняя тот же атрибут имени пользователя и базу поиска с правильным синтаксисом:

searchBase: 'ou=users,dc=contoso,dc=com',
searchFilter: '(cn={{Username}})'

Это должно работать для аутентификации пользователей со следующим шаблоном dn:

cn=<username>,<searchBase>  =>  cn=foo,ou=users,dc=contoso,dc=com

Вышеприведенное описание основано на вашей предыдущей конфигурации, но никто не может догадаться, как пользователь dn выглядит в вашем каталоге без дополнительной информации. Просто отметьте, что учетная запись менеджера (bindDN) и обычные пользователи обычно не используют один и тот же шаблон / структуру dn, а атрибут имени пользователя cn в вашем фильтре может быть неправильным.

Тем не менее, довольно очевидно определить структуру dn по заданной строке dn пользовательской записи, например, если атрибут username равен uid, а база пользователей расположена в ou=people:

dn: uid=foo,ou=people,dc=contoso,dc=com
=> searchBase: 'ou=people,dc=contoso,dc=com'
=> searchFilter: '(uid={{Username}})'

Теперь, если вы решили передать учетные данные через тело запроса, usernameField и passwordField должны быть установлены в соответствии, например, с. со следующим телом { "user": "test", "pass": "test" } вы должны установить:

    //credentialsLookup: basicAuth,
    usernameField: user,
    passwordField: pass

Но если вы предпочитаете устанавливать учетные данные через заголовок авторизации, тогда вы используете credentialsLookup с желаемым типом аутентификации и задаете его в Вкладка авторизации в Почтальоне.

Обратите внимание, что если вы установите оба поля credentialsLookup и два других, то credentialsLookup выиграет, даже если поиск не удастся (откат невозможен).

...