我正在尝试使用passport-ldapauth npm验证openLDAP用户名和密码。执行以下代码时,我总是收到错误
{ message: 'Missing credentials' }
。请帮助我解决我的代码有什么问题。
var connect = require('connect'),
app = connect(),
passport = require('passport'),
LdapStrategy = require('passport-ldapauth');
// Credentials from the free LDAP test server by forumsys
// More info at: http://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/
var OPTS = {
server: {
url: 'ldap://<ip>',
bindDn: '<admin username>',
bindCredentials: '<admin password>',
usernameField: "<passing actual username>",
passwordField: "<password>"
}
};
passport.use(new LdapStrategy(OPTS));
app.use(passport.initialize());
app.use(connectRoute(function (router) {
router.post('/login', function (req, res, next) {
passport.authenticate('ldapauth', {session: false}, function (err, user, info) {
console.log(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);
});
}))
app.listen(8080);
有关详细信息,请参阅此badRequestMessage flash message for missing username/password (default: 'Missing credentials')
答案 0 :(得分:7)
这是我的配置:
var passport = require('passport');
var LdapStrategy = require('passport-ldapauth').Strategy;
var OPTS = {
server: {
url: '<ldap server>',
bindDn: '<admin username>',
bindCredentials: '<admin password>',
searchBase: '<base dn>',
searchFilter: '(sAMAccountName={{username}})'
}
};
passport.use(new LdapStrategy(OPTS));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
usernameField
中的passwordField
和OPTS
是可选的。我的程序使用默认值username
和password
。如果设置了usernameField
,则需要将searchFilter
修改为(sAMAccountName={{<usernameField value>}})
或(uid={{<usernameField value>}})
。
此外,为了在会话中存储登录状态,需要express-session
模块。会话配置如下:
var session = require('express-session');
app.use(session({
secret: 'ldap secret',
resave: false,
saveUninitialized: true,
cookie : { httpOnly: true, maxAge: 2419200000 } /// maxAge in milliseconds
}));
然后,您可以将LDAP身份验证用作:
app.post('/login', passport.authenticate('ldapauth', {
successRedirect: '/users/profile', failureRedirect: '/login'
}));
答案 1 :(得分:1)
根据passport-ldapauth提供的文档,服务器的值对象不包含 usernameField 和 passwordField 。您的策略应该如下:
var OPTS = {
server: {
url: 'ldap://<ip>',
bindDn: '<admin username>',
bindCredentials: '<admin password>'
},
usernameField: "<field containing username>",
passwordField: "<field containing password>"
};
但正如G Chen在回答中提到的那样,usernameField和passwordField是可选的。
答案 2 :(得分:1)
请检查以下代码,其中必须执行用户的基本身份验证。必须验证用户登录凭据时,此代码才有效。
我们需要使用3个字段即。 usernameField,passwordField和credentialsLookup
`var basicAuth = require('basic-auth');
var OPTS = {
server: {
url: Constants.LDAP_SERVER_URL_STRING,
bindDn: Constants.LDAP_ADMIN_STRING,
bindCredentials: Constants.LDAP_PASSWORD_STRING,
// searchBase: Constants.LDAP_SEARCHBASE_STRING,
// searchFilter: Constants.LDAP_SEARCHFILTER_STRING
// reconnect: true
},
usernameField: username,
passwordField: password,
credentialsLookup: basicAuth
};
像Userbooster light这样的LDAP管理工具对于理解身份验证过程的发生方式非常有用。
searchBase,searchFilter等字段没用。然而,免责声明是您需要测试是否真实
答案 3 :(得分:1)
var basicAuth = require('basic-auth');
var LdapAuth = require('ldapauth-fork');
var username: string = req.body.username;
var password: string = req.body.password;
var ldap = new LdapAuth({
url: Constants.LDAP_SERVER_URL_STRING,
bindDN: Constants.LDAP_BIND_DN_STRING,
bindCredentials: Constants.LDAP_PASSWORD_STRING,
searchBase: 'uid=' + username + ',' + Constants.LDAP_SEARCHBASE_STRING,
searchFilter: Constants.LDAP_SEARCHFILTER_STRING
// reconnect: true
});
ldap.authenticate(username, password, function(err, user) {
if (err) {
console.log("login Error");
res.send({ success : false, message : 'authentication failed' });
} else if(!user.uid) {
console.log("user not found Error");
res.send({ success : false, message : 'authentication failed' });
} else if(user.uid) {
console.log("success : user "+ user.uid +" found ");
}
});
答案 4 :(得分:0)
可能问题不是由passport-ldapauth
引起的。您的帖子请求可能存在一些问题。在使用[usernameField]
之前,请检查您的请求中是否有[passwordField]
,passport.authenticate
。
答案 5 :(得分:0)
请使用“LDAP身份验证”
检查NPM您会遇到一个名为ldapauth-fork的软件包。这个包似乎工作正常。
答案 6 :(得分:0)
请勿在DN中使用管理员用户名或密码。如果您想对用户进行身份验证,您只需要用户自己的用户名和密码。
dn
是LDAP中的绑定DN。取决于您的ldap服务器配置,它会有所不同。使用ldapsearch
进行试验,找出您应该使用哪一个。
我写了一个基于passport-ldapauth的npm模块来简化ldap身份验证登录。请查看:https://github.com/shaozi/express-passport-ldap-mongoose
简单用法:
LdapAuth.init(CONFIG.ldap.dn, CONFIG.ldap.url, app,
(id) => User.findOne({ uid: id }).exec(),
(user) => User.findOneAndUpdate({ uid: user.uid }, user, { upsert: true, new: true }).exec()
)
答案 7 :(得分:0)
将ldapauth-fork / lib / ldapauth.js bindProperty从dn更改为upn:
this.opts.bindProperty || (this.opts.bindProperty = 'userPrincipalName')
导致用户名认证。
不需要完整的dn。
答案 8 :(得分:0)
浪费大量时间后,我终于能够修复它。我的一些发现
{{username}}
替换发生在ONLY ON searchFilter
。我是在searchBase
username
和password
,并且您使用了正确的body-parser
,否则护照将无法提取由于护照没有显示任何错误,因此它无声地失败,请在库的两个位置添加调试器
在ldapauth.js
中搜索LdapAuth.prototype.authenticate
,您将看到ldapauth能够提取密码/用户名
在strategy.js
中搜索ldap.authenticate
,您将看到什么是实际错误