Skip to content
This repository has been archived by the owner on Mar 8, 2018. It is now read-only.

LDAP Integration with Passport.js

jedireza edited this page Dec 10, 2014 · 3 revisions

This guide was sent in by @solomongifford. If there are any typos or changes that need to be made, please open an issue and mention that handle.

Step 0:

$ npm install passport-ldapauth --save

Step 1:

We need to tell the login process to use the ldapauth authenticate by changing the following line in /views/login/index.js from

req._passport.instance.authenticate('local', function(err, user, info) {

to

req._passport.instance.authenticate('ldapauth', function(err, user, info) {

Step 2:

Replace the Passport "Local" strategy with the Ldap Strategy in /passport.js by replacing

LocalStrategy = require('passport-local').Strategy,

with

var LdapStrategy = require('passport-ldapauth').Strategy,

and then replacing the entire

passport.use(new LocalStrategy(
  // ...
));

with

passport.use(new LdapStrategy(app.config.LDAPOPTS,
  function(LDAPUser, done) {
    var conditions = { isActive: 'yes' };
    if (LDAPUser.mail && LDAPUser.mail.indexOf('@')) {
      conditions.email = LDAPUser.mail;
    }
    else {
      conditions.username = LDAPUser.uid;
    }
    app.db.models.User.findOne(conditions, function(err, user) {
      if (err) {
        return done(err);
      }

      if (!user) {
        var userFieldsToSet = {
          isActive: 'yes',
          username: LDAPUser.uid,
          email: LDAPUser.mail.toLowerCase(),
          search: [
            LDAPUser.uid,
            LDAPUser.mail.toLowerCase()
          ]
        };

        app.db.models.User.create(userFieldsToSet, function(err, user) {
          if (err) {
            return done(err);
          }

          var accountFieldsToSet = {
            isVerified: 'yes',
            'name.full': user.username,
            user: {
              id: user._id,
              name: user.username
            },
            search: [
              user.username
            ]
          };

          app.db.models.Account.create(accountFieldsToSet, function(err, account) {
            if (err) {
              return done(err);
            }

            user.roles.account = account._id;
            user.save(function (err, user) {
              if (err) {
                return done(err);
              }

              return done(null, user);
            });
          });
        });
      }
      else {
        return done(null, user);
      }
    });
  }
));

Taking note of the first few lines where the conditions.email and conditions.username are set. If your ldap setup is different you may not have email and uid attributes and you will need to plan accordingly.

Step 3:

Remove the signup routes, password reset routes, social login routes, etc from from /routes.js, /layouts/default.jade, and any other places they may exist. You don't have to remove code references, just the links in the routes and interface.

Step 4:

Finally, in /config.js, add an ldap config section:

exports.LDAPOPTS = {
  server: {
    url: 'ldap://127.0.0.1:389',
    adminDn: "cn=Directory Manager",
    adminPassword: 'ldappassword',
    searchBase: 'dc=example,dc=com',
    searchFilter: '|(uid={{username}})(mail={{username}})',
    usernameField: 'uid',
    passwordField: 'userPassword',
  }
};

Notes:

  1. Some LDAP installations may require the adminDn to be a user with appropriate privileges.
  2. adminDn may soon be renamed to bindDn. See the passport-ldapauth module for details.
  3. The searchFilter above assumes the username is in ldap's uid and the email is in mail. Modify per your installation.