diff --git a/README.md b/README.md index fc51e295..b85b1d57 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ So far, `everyauth` enables you to login via: Box.net OpenId RocketLabs Development, Andrew Mee, Brian Noguchi - LDAP (experimental; not production-tested) + LDAP / ActiveDirectory Marek Obuchowicz from Korekontrol Windows Azure Access Control Service (ACS) Dario Renzulli, Juan Pablo Garcia, Matias Woloski from Southworks @@ -2237,21 +2237,25 @@ everyauth.box.configurable(); ### LDAP -The LDAP module is still in development. Do not use it in production yet. +The LDAP module is not tested throughly yet, however it is used in production by some organizations already. Feedback is very welcome. Install OpenLDAP client libraries: - $ apt-get install slapd ldap-utils + $ sudo apt-get install ldap-utils -Install [node-ldapauth](https://github.com/joewalnes/node-ldapauth): +Install [node-ldapauth](https://github.com/marek-obuchowicz/node-ldapauth): ```javascript var everyauth = require('everyauth') , connect = require('connect'); everyauth.ldap - .host('your.ldap.host') - .port(389) + .ldapUrl('ldap(s)://your.ldap.host') + .adminDn('DN for bind') + .adminPassword('Password for bind user') + .searchBase('e.g. ou=users,dc=example,dc=com') + .searchFilter('e.g. (uid={{username}})') + .requireGroupDn('e.g. cn=Administrators,ou=Groups,dc=example,dc=com') // The `ldap` module inherits from the `password` module, so // refer to the `password` module instructions several sections above diff --git a/lib/modules/ldap.js b/lib/modules/ldap.js index 18f8ac06..a95348ff 100644 --- a/lib/modules/ldap.js +++ b/lib/modules/ldap.js @@ -1,28 +1,67 @@ var passwordModule = require('./password'); +var LdapAuth = require('ldapauth'); var ldap = module.exports = passwordModule.submodule('ldap') .configurable({ - host: 'the ldap host' - , port: 'the ldap port' + ldapUrl: 'ldap server url' + , adminDn: 'ldap bind dn' + , adminPassword: 'ldap bind password' + , searchBase: 'ldap search base' + , searchFilter: 'ldap search filter' + , requireGroupDn: 'ldap (option) required group DN' }) .authenticate( function (login, password, req, res) { var promise = this.Promise(); - ldapauth.authenticate(this.host(), this.port(), login, password, function (err, result) { + var ldapauth = new LdapAuth({ + url: this._ldapUrl, + adminDn: this._adminDn, + adminPassword: this._adminPassword, + searchBase: this._searchBase, + searchFilter: this._searchFilter, + requireGroupDn: this._requireGroupDn, + cache: true + }); + ldapauth.authenticate(login, password, function (err, result) { var user, errors; if (err) { - return promise.fail(err); + // return promise.fail(err); + if (typeof err == 'string') { + return promise.fulfill(['LDAP Error: ' + err]); + } else { + return promise.fulfill(['LDAP Error: ' + err.message]); + } } if (result === false) { errors = ['Login failed.']; return promise.fulfill(errors); - } else if (result === true) { - user = {}; - user[this.loginKey()] = login; - return promise.fulfill(user); + } else if (typeof result == 'object') { + if (result.uid == login) { + user = {}; + user['id'] = login; + console.log("LDAP: positive authorization for user " + result.uid + "") + return promise.fulfill(user); + } else { + return promise.fulfill(['LDAP Error: result does not match username', result]) + } } else { - throw new Error('ldapauth returned a result that was neither `true` nor `false`'); + console.log('ldapauth returned an unknown result:'); + console.log(result); + return promise.fulfill(['Unknown ldapauth response']); } }); return promise; - }); + }) + .addToSession( function (sess, user, errors) { + var _auth = sess.auth || (sess.auth = {}); + if (user) + _auth.ldap = { + userId: user[this._userPkey] + }; + _auth.loggedIn = !!user; + }) + .getRegisterPath('/nonexistant/register') + .postRegisterPath('/nonexistant/register') + .registerUser( function (newUserAttributes) {}); + +;