使用NodeJS进行Active Directory身份验证

时间:2018-05-31 11:02:38

标签: node.js active-directory

我正在尝试构建一个NodeJS服务器,并计划使用该组织的Microsoft Active Directory进行身份验证。

我尝试了很多软件包(activedirectory,activedirectory2,ldapjs等)。

但它们似乎都不适合我。

我提供的是LDAP网址,以下是我的代码。

var ldapjs = require('ldapjs');

var config = { url: 'ldap://mycompany.com/dc=mycompany,dc=com'
           ,timeout: 10
           ,reconnect: {
              "initialDelay": 100,
              "maxDelay": 500,
              "failAfter": 5
              } 
        }

var username = "user_id@mycompany.com";
var password="password";

const ldapClient = ldapjs.createClient(config);


ldapClient.bind(username, password, function (err) {
console.log("Logging data...");
ldapClient.search('dc=mycompany,dc=com', function (err, search) {
 if (err) {
    console.log('ERROR: ' +JSON.stringify(err));
    return;
  }
search.on('searchEntry', function (err,entry) {
   if (err) {
    console.log('ERROR: ' +JSON.stringify(err));
    return;
  }
  else{
    var user = entry.object;
    console.log("Done.");
    return;
   }

   });
  });
});

有时候它会起作用,但是在大多数情况下我一直都会遇到以下错误(可能是在选择不同的IP时)

Error: connect ETIMEDOUT <ip address>:389
at Object.exports._errnoException (util.js:1018:11)
at exports._exceptionWithHostPort (util.js:1041:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)

让我感到困惑的是;如果我在C#应用程序中尝试使用相同的LDAP URL,它可以正常工作。

.Net app使用它的方式与NodeJS使用的方式有区别吗?

我可以通过某种方式更改代码以使其正常工作吗?

4 个答案:

答案 0 :(得分:4)

因为这是Google搜索结果中出现的第一个问题,并且花了我很多时间弄清楚如何使用Active Directory身份验证,所以我将分享This教程中的解决方案。

与我在互联网上找到的其他示例相比,它很容易理解和实现:

npm install --save activedirectory

// Initialize
var ActiveDirectory = require('activedirectory');
var config = {
    url: 'ldap://dc.domain.com',
    baseDN: 'dc=domain,dc=com'
};
var ad = new ActiveDirectory(config);
var username = 'john.smith@domain.com';
var password = 'password';
// Authenticate
ad.authenticate(username, password, function(err, auth) {
    if (err) {
        console.log('ERROR: '+JSON.stringify(err));
        return;
    }
    if (auth) {
        console.log('Authenticated!');
    }
    else {
        console.log('Authentication failed!');
    }
});

最困难的部分是弄清楚用户名使用什么后缀。

我遇到了错误:

错误:{“ lde_message”:“ 80090308:LdapErr:DSID-0C090400,注释: AcceptSecurityContext错误,数据52e,v1db1 \ u0000”,“ lde_dn”:空}

在最后设置正确的后缀之前,对我来说是这样的:
var username = 'john.smith@foo.companyname.com

答案 1 :(得分:0)

我首先通过使用npm:express-ntlm获取了发出请求的用户名来完成了这项工作。然后使用这些信息,我使用npm:activedirectory来向Active Directory查询该用户的详细信息。

app.use(
  ntlm({
    domain: process.env.DOMAIN,
    domaincontroller: process.env.DOMAINCONTROLLER
  })
);

...

app.use("/", authenticate, require("./routes/index"));

在经过身份验证的中间件中,我现在可以访问包含

的req.ntlm
{ DomainName: '...',
  UserName: '...',
  Workstation: '...',
  Authenticated: true }

我设置了ActiveDirectory对象,并记下了“ bindDN”和“ bindCredentials”而不是“ username”和“ password”:

var ad = new ActiveDirectory({
  url: process.env.DOMAINCONTROLLER,
  baseDN: process.env.BASEDN,
  bindDN: process.env.USERNAME,
  bindCredentials: process.env.PASSWORD
});

然后,您可以像npm:activedirectory文档中一样使用广告对象:

ad.findUser(req.ntlm.UserName, (err, adUser) => {
    ...
});

findUser返回诸如名字和姓氏,电子邮件地址之类的东西,这是我所需要的,但是您可以轻松地将其分为几类。

答案 2 :(得分:0)

我怀疑您遇到的是以下事实:活动目录(AD)高度可用,并且并非总是100%的域控制器都处于联机状态。 C#似乎有某种方法可以检测哪些未在线?

将HA名称用于域名时,我也遇到过类似的经历。

在这种情况下,与您的AD管理员进行对话并获得应该为您的服务器所在的站点提供服务的AD服务器,并通过IP地址或DNS直接与该服务器对话。

希望有帮助。

答案 3 :(得分:-1)

配置对象指定10毫秒超时。这似乎很短。您要暂停10秒吗?

JS Documentation

您是否在C#中使用LdapConnection.Timeout对象?那期望几秒钟。

C# Documentation