Серверная сторона NodeJS - нужен идентификатор окна клиента - PullRequest
0 голосов
/ 13 декабря 2018

(приложение для внутренней сети) Я использую ReactJS с NodeJS в качестве API на стороне сервера для доступа к различным ресурсам (таким как профиль активного каталога пользователя).Мне нужно интегрироваться с Active Directory, не запрашивая у пользователя учетные данные.

Использование ActiveDirectory для узла (npm i activedirectory) Я могу запросить AD с использованием LDAP для жестко закодированного sAMAccountName, используя код ниже.

ad.findUser(sAMAccountName, function(err, user) {
    if (err) {
      console.log('ERROR: ' + JSON.stringify(err));
    }

    if (!user) console.log('User: ' + sAMAccountName + ' not found.');
    else {
      thisUser = user;
    }
  });

Но я не могу понять, как подобрать текущий идентификатор пользователя при вызове API.

В этих 2 примерах вместо идентификатора пользователя «Сервер» вместоидентификатор клиента:

const user = process.env;
const user = require('os').userInfo().username;

В .net я обычно делал бы это с

string NTID = HttpContext.Current.User.Identity.Name;

Так есть ли способ в NodeJS, работающем на сервере, получить доступ к идентификатору пользователя клиента?

--------- ОБНОВЛЕНИЕ: -----------

Я пытался реализовать решениениже, используя passport-windowsauth, но не могу заставить его работать.У меня есть файл web.config, настроенный так:

<iisnode watchedFiles="*.js;node_modules\*;routes\*.js;views\*.jade" promoteServerVars="LOGON_USER,AUTH_USER" />
<security>
     <authentication>
          <anonymousAuthentication enabled="true" />
          <windowsAuthentication enabled="true" />
     </authentication>
</security>

Для конфигурации Azure установлено значение:

enter image description here

ЭтоФункция, которую я вызываю, когда нажимаю кнопку для запуска аутентификации:

activeDirectory = () => {
    let url = '';
    //Default to current user when in dev
    if (
      window.location.href.indexOf('localhost') > -1
    ) {
      url = 'http://localhost:5000/express-passport';
    } else {
      url = '/express-passport';
    }
    axios({
      method: "GET",
      url: url,
      withCredentials: true
    })
      .then(response => {
        console.log("Done: ", response.data);
      })
      .catch(error => {
        console.log("An error occurred - ", error);
      });
};

И это код маршрута сервера NodeJs:

const passport = require("passport");
const WindowsStrategy = require("passport-windowsauth");

module.exports = app => {
  let thisUser = {};
  passport.use(
    new WindowsStrategy(
      {
        ldap: {
          url: "ldap://somethingldap.somewhere.com/CN=,DC=,DC=,DC=,DC=",
          base: "CN=,DC=,DC=,DC=,DC=",
          bindDN: "serviceAccountDetailsHere",
          bindCredentials: "masked"
        }
      },
      function(profile, done) {
        thisUser = profile;
        console.log("Profile:", profile);
      }
    )
  );
  app.get(
    "/express-passport",
    function(req, res, next) {
      passport.authenticate("WindowsAuthentication", function(
        error,
        user,
        info
      ) {
        // log everything to console
        console.log(error);
        console.log(user);
        console.log(info);

        if (error) {
          res.status(401).send(error);
        } else if (!user) {
          res.status(401).send(info);
        } else {
          next();
        }

        res.status(401).send(info);
      })(req, res);
    },

    // function to call once successfully authenticated
    function(req, res) {
      res.status(200).send("logged in!");
    }
  );
};

Итак, теперь, когда открывается страница, я нажимаюКнопка, ожидая, что это аутентифицируется.Появляется всплывающее окно с запросом моих учетных данных, которые я ввожу, но всплывающее окно просто исчезает и появляется снова и снова.Я явно делаю что-то неправильно ...

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018

Ваша самая большая проблема будет заключаться в том, чтобы это работало на вашем компьютере MacOS таким образом, чтобы его можно было без проблем перенести на компьютер с Windows и работать так же.

node-sspi Пакет, вероятно, самый простой, но он также предназначен только для Windows.

Я думаю, что вам лучше всего использовать модуль passport-windowsauth для Passport.js и использоватьэто с LDAP, так как вы можете делать запросы LDAP к AD из любой ОС.

На сервере поместите его за IIS и следуйте их инструкциям в разделе Интегрированная аутентификация , чтобы настроить IIS с аутентификацией Windows насделайте вход в систему легким для пользователей.

На вашем компьютере MacOS, разумеется, вы не сможете этого сделать.Я думаю, что лучшее, что вы можете сделать для MacOS - это то, что он будет запрашивать у вас учетные данные.Вам придется проверить это.Я не уверен, будет ли он выполнять проверку подлинности без IIS, как это обычно происходит с (я не думаю, что это будет).Если нет, вы можете создать отдельную страницу входа в систему, следуя их инструкциям Неинтегрированная аутентификация , и вы используете ее только на своем компьютере разработчика.

При фактическом вызове passport.use()Единственная разница между ними - integrated: false.Таким образом, вы можете обнаружить, что вам придется установить это по-разному для локального разработчика по сравнению с сервером (надеюсь, ваш код может быть обнаружен, если вы находитесь на своем компьютере разработчика, и автоматически установите значение false).

Так что дау вас будет другое поведение при входе в систему между вашим устройством разработки и сервером, но, по крайней мере, вы сможете продвигать свой код как есть и работать в обоих местах.

0 голосов
/ 15 января 2019

Ниже приведено решение, которое я использовал для этого.Это комбинация из 2 пакетов -

express-ntlm

и

ActiveDirectory

ntlm isиспользуется для получения учетных данных пользователя из браузера (некоторым пользователям может потребоваться предоставить эти учетные данные, если это будет предложено).Как только ntlm имеет userID, я использую его для запроса к активному каталогу, чтобы получить более подробную информацию для пользователя.Причина для 2 модулей состоит в том, что ntlm предоставляет только 3 поля - UserName, DomainName и Workstation.В моем случае мне понадобился адрес электронной почты, имя, фамилия и т. Д.

https://www.npmjs.com/package/express-ntlm

https://www.npmjs.com/package/activedirectory

const ntlm = require('express-ntlm');
const ActiveDirectory = require('activedirectory');

module.exports = app => {
  const config = {
    url: 'ldap://something.somewhere.com',
    baseDN: 'CN=a,DC=b,DC=c',
    username: '',
    password: ''
  };

  app.use(
    //This is for getting the users MS ID only
    ntlm()
  );

  app.get(‘/apiName/’, (req, res) => {
    let sAMAccountName = req.ntlm.UserName;
    const ad = new ActiveDirectory(config);
    var userDetails = {
      Email: '',
      FirstName: '',
      LastName: ''
    };
    ad.findUser(sAMAccountName, (err, user) => {
      if (err) {
        console.log('ERROR: ' + JSON.stringify(err));
      }

      if (!user) console.log('User: ' + sAMAccountName + ' not found.');
      else {
        userDetails.Email = user.mail;
        userDetails.FirstName = user.firstName;
        userDetails.LastName = user.lastName;
      }
      res.json(userDetails);
      res.end();
    });
    });
  });
};
0 голосов
/ 20 декабря 2018

Чтобы ответить на ваш вопрос, как вы упомянули выше But what I can't figure out, is how to pick up the current user ID when they call the API.

Кажется, что вышеупомянутый код обернут в функцию, которая используется в качестве обратного вызова обработчика маршрута fn.говоря это, я имею в виду, что вы определенно будете иметь доступ к req и res aka request и response аргументам API-функции.

например: -

module.exports = {
  routeHanlder: function(req, res) {
      ad.findUser(sAMAccountName, function(err, user) {
         if (err) {
           console.log('ERROR: ' + JSON.stringify(err));
         }

         if (!user) console.log('User: ' + sAMAccountName + ' not found.');
         else {
          thisUser = user;
         }
      });
  }
}

такв приведенном выше примере аргумент req содержит всю информацию о клиенте, которую вы хотите получить, откуда приходит запрос, каковы заголовки запроса и т. д.

, как вы упомянули в своем вопросе, что string NTID = HttpContext.Current.User.Identity.Name;используя HttpContext, вы можете получить личность пользователя.Используя req, вы получите информацию о клиенте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...