ActiveDirectoryStrategy的验证程序函数未在Passport.js中调用

时间:2018-08-13 19:45:50

标签: javascript node.js express passport.js

我有一个足够简单的快速应用程序,它尝试使用Active Directory来验证用户身份。这是我的设置:

const express = require('express');
const session = require('express-session');
const passport = require('passport');
const ActiveDirectoryStrategy = require('passport-activedirectory');

const PORT = process.env.PORT || 8080;
// AD configuration. Real values omitted.
const config = {
    url: 'ldaps://...',
    baseDN: '...',
    username: '...',
    password: '...'
};

const app = express();

app.use(session({
    secret: 'mysessionsecret',
    resave: true,
    saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());

passport.use('ad', new ActiveDirectoryStrategy(
    {
        ldap: config
    },
    (profile, ad, done) => {
        // The problem is here! This never gets called!
        console.log('ActiveDirectoryStrategy activated.');
        done('ActiveDirectoryStrategy not implemented.');
    }
));

// route middleware to ensure user is logged in
const isLoggedIn = (req, res, next) =>
    req.isAuthenticated() ? next() : res.redirect('/auth');

app.get('/', isLoggedIn, (req, res) => {
    res.end('You are logged in.');
});

app.get('/unsecured', (req, res) => {
    res.end('You are not logged in.');
});

app.get('/auth', passport.authenticate('ad', {
    successRedirect: '/',
    failureRedirect: '/unsecured'
}));

app.listen(PORT);
console.log('Listening on port ' + PORT);

但是,我为构造函数ActiveDirectoryStrategy传递的验证函数从未被调用。 (这是带有签名(profile, ad, done)的函数)。

我确信LDAP配置没有问题,因为我可以使用具有相同参数的activedirectory模块正常访问活动目录:

const ActiveDirectory = require('activedirectory');
const ad = new ActiveDirectory(config);

ad.findUser('username', (err, user) => {
    if (err) {
        return console.log(err);
    }

    console.log(JSON.stringify(user));
    // prints an object with user's info
});

所以我的路由一定有问题。我究竟做错了什么?为什么我的验证程序函数没有被调用?

1 个答案:

答案 0 :(得分:0)

问题是我误解了。我认为Passport.js的身份验证中间件将为我执行NTLM握手。不是这种情况。 passport-activedirectory实际上需要像IISNode这样的东西才能在其前面运行,以执行NTLM握手。由于该请求不包含身份验证信息,所以

结果,我决定使用express-ntlm中间件。 express-ntlm为您提供了UserNameDomainNameWorkstation属性供您使用。但是,如果出于某种原因要获取完整的AD配置文件,则可以设置自定义护照策略,如下所示:

const ActiveDirectory = require('activedirectory');
const CustomStrategy = require('passport-custom');

passport.use('ntlm-ad-backend', new CustomStrategy((req, done) => {
    let username = req.ntlm.UserName;

    AD.findUser(username, (err, profile) => {
        if (err) {
            console.log(err);
            done(err);
        }

        if (!profile) {
            done(new Error(`User ${req.ntlm.UserName} not found in Active Director.`));
        } else {
            done(null, profile);
        }
    });
}));

然后

app.get('/auth', passport.authenticate('ntlm-ad-backend', {
    successRedirect: '/',
    failureRedirect: '/unsecured'
}));

请注意,您还必须实现serializeUserdeserializeUser