2017-08-21 211 views
1

我一直在努力使用passport-ldapauth幾天,並且我沒有更多的想法,我做錯了什麼。在Node.js上使用passport-ldapauth進行LDAP身份驗證

簡而言之,我有一個使用兩種護照策略的項目:本地和LDAP。本地策略對我來說非常合適,但LDAP是有問題的。

我有一個AD的只讀用戶(我們稱之爲「ldap-read-only-admin」),我可以通過外部LDAP客戶端與此用戶連接並查看相關的OU。我也三重檢查了SearchBase,它似乎是正確的。

但是,當將相同的配置傳遞給passport-ldapauth時,它似乎無法綁定用戶憑證(我猜)。任何想法如何調試這將非常感激。

這是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"); 

這是routes.js(相關部分):

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


} 

這是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); 
     } 

    )); 

    }; 

回答

2

經過五個小時的嘗試,我設法解決了我的問題。

首先,我的「ldap-read-only-admin」與其他用戶位於相同的OU下,因此我必須將整個路徑放到bindDN字符串中的ldap-read-only-admin。其次,我需要使用sAMAccountName而不是uid。第三,我必須從LdapStrategy函數中刪除req。

這裏是passport.js LDAP登錄的樣子:

// ========================================================================= 
    // 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); 
    } 

)); 

希望它會幫助別人。

+0

很高興。我正要提出這個建議。幾個月前我遇到過一些問題。 –