在Node.js上使用passport-ldapauth进行LDAPauthentication

我一直在与护照ldapauth挣扎了几天,我没有更多的想法,我做错了什么。

简而言之,我有一个使用两种护照策略的项目:本地和LDAP。 本地策略对我来说是完美的,但LDAP是有问题的。

我有一个AD的只读用户(我们称之为“ldap-read-only-admin”),我可以通过外部LDAP客户端连接到这个用户并查看相关的OU。 我也三重检查了SearchBase,这似乎是正确的。

但是,当将相同的configuration传递给passport-ldapauth时,它似乎无法绑定用户凭据(我猜)。 任何想法如何debugging这将非常感激。

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

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

首先,我的“ldap-read-only-admin”与其他用户在相同的OU下,所以我不得不把整个path放在bindDNstring中的ldap-read-only-admin。 其次,我需要使用sAMAccountName而不是uid。 第三,我必须从LdapStrategy函数中删除req。

以下是passport.js中的ldaplogin方式:

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

希望它能帮助别人。