【问题标题】:LDAP authentication using passport-ldapauth on Node.js在 Node.js 上使用 passport-ldapauth 进行 LDAP 身份验证
【发布时间】:2018-01-29 07:22:09
【问题描述】:

几天来,我一直在为护照 ldapauth 苦苦挣扎,但我不知道我做错了什么。

简而言之,我有一个项目使用两种护照策略:本地和 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);
        }

    ));   

    };

【问题讨论】:

    标签: node.js express ldap passport.js


    【解决方案1】:

    又经过五个小时的尝试,我设法解决了我的问题。

    首先,我的“ldap-read-only-admin”与其他用户在同一个 OU 下,因此我必须将 ldap-read-only-admin 的整个路径放在 bindDN 字符串中。其次,我需要使用 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);
        }
    
    )); 
    

    希望对某人有所帮助。

    【讨论】:

    • 很高兴。我正要这么建议。几个月前我遇到了一些问题。
    • 我写了一个 npm 模块来简化它。查看github.com/shaozi/express-passport-ldap-mongoose。您只需要使用 dn、ldapurl 调用 init,并将您自己的用户查找和更新函数传递给它。
    猜你喜欢
    • 2020-02-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 2022-07-11
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    相关资源
    最近更新 更多