Reputation: 559
I am trying to authenticate openLDAP username and password using passport-ldapauth npm. While executing the below code I am always getting error as
{ message: 'Missing credentials' }
. Kindly help me what is wrong with my code.
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);
For more details, please see this badRequestMessage flash message for missing username/password (default: 'Missing credentials')
Upvotes: 6
Views: 25190
Reputation: 2233
After wasting lot of time, I finally able to fix it. Some my findings
{{username}}
replacement happens ONLY ON searchFilter
. I was doing it on searchBase
username
and password
filed and you have used correct body-parser
otherwise passport will notable to extractAs passport was not showing any error it was failing silently, add debugger in two places in the of the library
In ldapauth.js
search for LdapAuth.prototype.authenticate
here you will able to see ldapauth is able to extract password/username
In strategy.js
search for ldap.authenticate
here you will be able to see what is the actuall error
Upvotes: 0
Reputation: 1
A Change in ldapauth-fork/lib/ldapauth.js bindProperty from dn to upn :
this.opts.bindProperty || (this.opts.bindProperty = 'userPrincipalName')
causes username authentication.
Full dn is not needed.
Upvotes: 0
Reputation: 3485
Don't use admin username or password in DN. If you want to authenticate a user, all you need is the user's own username and password.
The dn
is the Bind DN in LDAP. Depends on your ldap server configuration, it varies. Use ldapsearch
to experiment to find out which one should you use.
I wrote an npm module based on passport-ldapauth to simplify the ldap authentication login.Please check it out at: https://github.com/shaozi/express-passport-ldap-mongoose
Simple usage:
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()
)
Upvotes: 0
Reputation: 21
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 ");
}
});
Upvotes: 1
Reputation: 21
Please check NPM with "LDAP Authentication"
You will come across a package called ldapauth-fork. This package seems to be working correctly.
Please check the following link https://www.npmjs.com/package/ldapauth-fork
Upvotes: 0
Reputation: 21
Please check the following Code where Basic Authentication of the user has to be performed. This code works when a user login credentials have to be verified.
We need to use 3 fields viz. usernameField, passwordField and 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
};
LDAP Administration tools like Userbooster light are very useful in understanding how the authentication process happens.
Fields such as searchBase, searchFilter are of no use. The disclaimer however is that you need to test to see if it is true
Upvotes: 1
Reputation: 21
Maybe the issue is not caused by the passport-ldapauth
. There may be some problems with your post requests. Check if there are [usernameField]
, [passwordField]
in your request before using passport.authenticate
.
Upvotes: 0
Reputation: 453
According to the documentation provided by passport-ldapauth, the object which is the value of server does not contain the usernameField and passwordField. Your strategy should look like:
var OPTS = {
server: {
url: 'ldap://<ip>',
bindDn: '<admin username>',
bindCredentials: '<admin password>'
},
usernameField: "<field containing username>",
passwordField: "<field containing password>"
};
But as G Chen mentions in his answer, the usernameField and passwordField are optional.
Upvotes: 1
Reputation: 199
Here is my configuration:
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);
});
The usernameField
and passwordField
in OPTS
are optional. My program is using the default value username
and password
. If the usernameField
is set, you need to modify searchFilter
as (sAMAccountName={{<usernameField value>}})
or (uid={{<usernameField value>}})
.
Also, in order to store the login status in your session, express-session
module is required. The session configuration is like:
var session = require('express-session');
app.use(session({
secret: 'ldap secret',
resave: false,
saveUninitialized: true,
cookie : { httpOnly: true, maxAge: 2419200000 } /// maxAge in milliseconds
}));
Then, you can use the LDAP authentication as:
app.post('/login', passport.authenticate('ldapauth', {
successRedirect: '/users/profile', failureRedirect: '/login'
}));
Upvotes: 8