2017-08-21 3 views
1

Je me bats avec passeport-ldapauth depuis quelques jours, et je n'ai plus d'idées sur ce que je fais de mal.Authentification LDAP en utilisant passport-ldapauth sur Node.js

En bref, j'ai un projet qui utilise deux stratégies de passeport: local et LDAP. La stratégie locale fonctionne parfaitement pour moi, mais LDAP est problématique.

J'ai un utilisateur en lecture seule pour AD (appelons-le "ldap-read-only-admin"), et je suis capable de se connecter avec cet utilisateur via un client LDAP externe et voir l'unité d'organisation pertinente. J'ai également vérifié trois fois la SearchBase, et il semble être correct.

Cependant, en passant la même configuration à passeport-ldapauth, il semble qu'il ne peut pas lier les informations d'identification de l'utilisateur (je suppose). Toutes les idées sur la façon de déboguer ce sera très apprécié.

C'est le app.js:

var express = require("express"); 
    var app  = express(); 
    var path = require("path"); 
    var session = require("express-session"); 
    var mongoose = require("mongoose"); 
    var passport = require("passport"); 
    var flash = require("connect-flash"); 
    var cookieParser = require("cookie-parser"); 
    var bodyParser = require("body-parser"); 
    var morgan = require("morgan"); 

    var configDB = require('./config/database.js'); 
    require('./config/passport.js')(passport); // pass passport for configuration 


    app.use(express.static(__dirname + '/public')); 

    app.set('view engine', 'ejs'); 

    //connect to the Database 
    var promise = mongoose.connect(configDB.url, { 
     useMongoClient: true, 
    });  

    app.use(morgan('dev')); // log every request to the console 
    app.use(cookieParser()); // read cookies (needed for auth) 
    //app.use(bodyParser()); // get information from html forms 
    app.use(bodyParser.urlencoded({ 
     extended: true 
    })); 
    app.use(bodyParser.json({ 
     extended: true 
    })); 

    // configuring passport 
    app.use(session({ secret: 'secret', resave: true, saveUninitialized: true })); // session secret 
    app.use(passport.initialize()); 
    app.use(passport.session()); // persistent login sessions 
    app.use(flash()); // use connect-flash for flash messages stored in session 


    require('./modules/routes.js')(app, passport); // load our routes and pass in our app and fully configured passport 


    //make Web server listen on a specific port 
    app.listen(3000); 

    logger.info("Listening on port 3000"); 

Ceci est routes.js (la partie pertinente):

module.exports = function(app, passport) { 
app.post('/', function(req, res, next) { 

    passport.authenticate('ldap-login', {session: true}, function(err, user, info) { 
    console.log("user: " + user); 
    console.log("info: " + JSON.stringify(info)); 
     if (err) { 
     return next(err); // will generate a 500 error 
     } 
     // Generate a JSON response reflecting authentication status 
     if (! user) { 
     return res.send({ success : false, message : 'authentication failed' }); 
     } 
     return res.send({ success : true, message : 'authentication succeeded' }); 
    })(req, res, next); 
    }); 


} 

Et ceci est passport.js:

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

    // load the user model 
    var User   = require('../modules/user.js'); 

    // expose this function to our app using module.exports 
    module.exports = function(passport) { 

     // ========================================================================= 
     // passport session setup ================================================== 
     // ========================================================================= 
     // required for persistent login sessions 
     // passport needs ability to serialize and unserialize users out of session 

     // used to serialize the user for the session 
     passport.serializeUser(function(user, done) { 
      done(null, user.id); 
     }); 

     // used to deserialize the user 
     passport.deserializeUser(function(id, done) { 
      User.findById(id, function(err, user) { 
       done(err, user); 
      }); 
     }); 


     // ========================================================================= 
     // LOCAL LOGIN ============================================================= 
     // ========================================================================= 

     passport.use('local-login', new LocalStrategy({ 

      passReqToCallback : true // allows us to pass back the entire request to the callback 
     }, 
     function(req, username, password, done) { // callback with email and password from our form 

      // find a user whose email is the same as the forms email 
      // we are checking to see if the user trying to login already exists 
      User.findOne({ username : username }, function(err, user) { 
       // if there are any errors, return the error before anything else 
       if (err) 
        return done(err); 

       // if no user is found, return the message 
       if (!user) 
        return done(null, false, req.flash('loginMessage', 'The username "' + username + '" is not found.')); // req.flash is the way to set flashdata using connect-flash 

       // if the user is found but the password is wrong 
       if (!user.validPassword(password)) 
        return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata 

       // all is well, return successful user 
       return done(null, user); 
      }); 

     })); 



     // ========================================================================= 
     // LDAP Login ============================================================== 
     // ========================================================================= 

     var opts = { 
      server: { 
        url: 'ldap://<ldap server address>:389', 
        bindDn: 'cn=ldap-read-only-admin', 
        bindCredentials: 'password', 
        searchBase: 'OU=XX1, OU=XX2, DC=domain, DC=local', 
        searchFilter: '(uid={{username}})',  
        // passReqToCallback : true 
        } 
     }; 

     passport.use('ldap-login', new LdapStrategy(opts, function(req, user, done) { 
      console.log("Passport LDAP authentication."); 
      done(null, user); 
     } 

    )); 

    }; 

Répondre

2

Après cinq heures d'essais, j'ai réussi à résoudre mon problème. Tout d'abord, mon "ldap-read-only-admin" était sous les mêmes unités d'organisation que les autres utilisateurs, donc j'ai dû mettre le chemin complet vers mon ldap-read-only-admin dans la chaîne bindDN. Deuxièmement, j'avais besoin d'utiliser sAMAccountName au lieu de uid. Et troisièmement, j'ai dû supprimer req de la fonction LdapStrategy.

Voici comment connexion ldap à passport.js ressemble:

// ========================================================================= 
    // LDAP Login ============================================================== 
    // ========================================================================= 

    var opts = { 
     server: { 
       url: 'ldap://<ldap server address>:389', 
       bindDn: 'cn=ldap-read-only-admin,OU=XX1, OU=XX2, DC=domain, DC=local', 
       bindCredentials: 'password', 
       searchBase: 'OU=XX1, OU=XX2, DC=domain, DC=local', 
       searchFilter: '(sAMAccountName={{username}})',  
       // passReqToCallback : true 
       } 
    }; 

    passport.use('ldap-login', new LdapStrategy(opts, function(user, done) { 
     console.log("Passport LDAP authentication."); 
     done(null, user); 
    } 

)); 

Espérons que cela aidera quelqu'un.

+0

Heureux. J'étais sur le point de suggérer cela. J'avais rencontré quelques problèmes il y a des mois. –