Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LDAP Authentication with NodeJS, Express, and Passport-ldapauth

I"m having trouble authenticating to an Active Directory Server with the tools/applications mentioned in the title.

I'm using a test AD environment found here Here are the relevant code snippets, if anyone has any suggestions I would really appreciate it.

Currently, the error i'm getting is "invalid username/password". I'm not sure if this is the bindDn account/pw or the one the user enters in the form. According to the passport-ldapauth project it's:

invalidCredentials flash message for InvalidCredentialsError
NoSuchObjectError, and 
/no such user/i LDAP errors (default: 'Invalid     username/password')

Thanks in advance.

CLIENT - auth.service.js

...

login: function(user, callback) {
var cb = callback || angular.noop;
var deferred = $q.defer();

$http.post('/auth/ldap', {
  email: user.email,
  password: user.password
}).
success(function(data) {
  $cookieStore.put('token', data.token);
  currentUser = User.get();
  deferred.resolve(data);
  return cb();
}).
error(function(err) {
  this.logout();
  deferred.reject(err);
  return cb(err);
}.bind(this));

return deferred.promise;
},

...

SERVER index.js

'use strict';

var express = require('express');
var passport = require('passport');
var auth = require('../auth.service');

var router = express.Router();

router.post('/', function(req, res, next) {
  passport.authenticate('ldapauth', function (err, user, info) {
    var error = err || info;
    if (error) return res.json(401, error);
    if (!user) return res.json(404, {message: 'Something went wrong, please try again.'});

    var token = auth.signToken(user._id, user.role);
    res.json({token: token});
  })(req, res, next)
});

module.exports = router;

SERVER passport.js

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

exports.setup = function (User, config) {
  passport.use(new LdapStrategy({
      usernameField: 'email',
      passwordField: 'password',
      server: {
        url: 'ldap://ldap.forumsys.com:389',
        bindDn: "cn=read-only-admin,dc=example,dc=com",
        bindCredentials: "password",
        searchBase: 'ou=mathematicians,dc=example,dc=com',
        searchFilter: 'uid={{username}}'
      }
    },
    function (user, done) {  
      return done(null, user);
    }
  ));
};
like image 960
user1554903 Avatar asked Jan 26 '15 21:01

user1554903


2 Answers

The problem is with the ou=mathematicians in the search base. There is the following mention in the comments on that web page:

The issue you are seeing is due to the fact that “uid=riemann” is a member of “ou=mathemeticians”, but does not reside under that ou. His membership in that ou is established by a uniqueMember attribute on “ou=mathemeticians”.

This should work (tried it even with ldapauth-fork which passport-ldapauth uses):

var opts = {
  server: {
    "url": "ldap://ldap.forumsys.com:389",
    "adminDn": "cn=read-only-admin,dc=example,dc=com",
    "adminPassword": "password",
    "searchBase": "dc=example,dc=com",
    "searchFilter": "(uid={{username}})",
  }
};
like image 114
vesse Avatar answered Oct 19 '22 00:10

vesse


For whose still lose your way, here is my code snippet in Typescript.

Server Side

import * as express from 'express'
import * as bodyParser from 'body-parser'
import * as cors from 'cors'
import * as passport from 'passport'
import * as ldapstrategy from 'passport-ldapauth'

// connect to LDAP server
const OPTS: ldapstrategy.Options = {
  server: {
    url: "ldap://ldap.forumsys.com",
    bindDN: "cn=read-only-admin,dc=example,dc=com",
    bindCredentials: 'password',
    searchBase: "dc=example,dc=com",
    searchFilter: "(uid={{username}})"
  }
}

passport.use(new ldapstrategy(OPTS))

// instantiate the server
const app = express()
// parse the request data automatically
app.use(bodyParser.json())
// allow cross origin resource sharing
app.use(cors())
// inject LDAP connection to express server
app.use(passport.initialize())

// listen to port defined
const port = process.env.PORT || 8085
app.listen(port, (): void => {
  console.log(`Listening on port ${port}`)
})

app.post('/login', (req: express.Request, res: express.Response, next: express.NextFunction): void | Response => {
  passport.authenticate('ldapauth', (err, user, info): void => {
    var error = err || info
    if (error) 
      res.send({
        status: 500,
        data: error
      })
    if (!user) 
      res.send({
        status: 404,
        data: "User Not Found"
      })
    else
      res.send({
        status: 200,
        data: user
      })
  })(req, res, next)
})

Client Side

Postman Example

like image 26
Lost Avatar answered Oct 19 '22 01:10

Lost