Active Directory authentication with NodeJS

人盡茶涼 提交于 2020-05-13 04:44:46

问题


I'm trying to build one NodeJS server and planning to use the organization's Microsoft Active Directory for authentication.

I tried the same with many packages (activedirectory, activedirectory2, ldapjs etc.)

But none of them seems to work for me.

I'm supplying the LDAP URL and below is my code.

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;
   }

   });
  });
});

Sometimes it works, but for most of the times I keep on getting following error (may be when it chooses a different 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)

What puzzles me is; if I try with the same LDAP URL in my C# application, it works fine.

Is there a difference in the way .Net app uses it than the way NodeJS uses?

Can I change my code in some way to make it work?


回答1:


I got this working by first getting the username that made the request with npm:express-ntlm. Then with this information, I use npm:activedirectory to query Active Directory for that user's details.

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

...

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

Inside my authenticate middleware I now have access to req.ntlm which contains

{ DomainName: '...',
  UserName: '...',
  Workstation: '...',
  Authenticated: true }

I setup the ActiveDirectory object, and note "bindDN" and "bindCredentials" instead of "username" and "password":

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

Then you can use the ad object like in the npm:activedirectory documentation:

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

findUser returns things like first and last name, email address, which is all I needed but you could easily look into groups.




回答2:


Because this is the first question that pops up in Google's search result, and it took me quite some time to figure out how to use Active Directory Authentication, I'm going to share the solution from This tutorial.

It was very easy to understand and implement comparing to other examples I've found on the internet:

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!');
    }
});

The most difficult part was to figure out what suffix to use for the username.

I was getting the error:

ERROR: {"lde_message":"80090308: LdapErr: DSID-0C090400, comment: AcceptSecurityContext error, data 52e, v1db1\u0000","lde_dn":null}

Before finally setting the right suffix, for me it was something like:
var username = 'john.smith@foo.companyname.com




回答3:


The configuration object specifies a 10 millisecond timeout. That seems pretty short. Were you going for a 10 second timeout?

JS Documentation

Are you using the LdapConnection.Timeout object in C#? That one expects seconds.

C# Documentation




回答4:


I suspect what you're experiencing is the fact that active directory (AD) is highly available and not always 100% of domain controllers are online. C# seems to have some method to detect which are not online possibly?

I have had similar experiences when using the HA Name for the domain which it looks like you did.

In these cases it helps to speak to your AD Administrator and get the AD Server that is supposed to be servicing the site your servers are in and speak directly to that one via IP Address or DNS.

Hope that helps.



来源:https://stackoverflow.com/questions/50622797/active-directory-authentication-with-nodejs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!