Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish LDAP implementation #470

Merged
merged 3 commits into from
Oct 15, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ So far, `everyauth` enables you to login via:
<tbody id=misc>
<tr> <td> <img src="https://github.com/bnoguchi/everyauth/raw/master/media/box.ico" style="vertical-align:middle"> Box.net <td>
<tr> <td> <img src="https://github.com/bnoguchi/everyauth/raw/master/media/openid.ico" style="vertical-align:middle" width="16px" height="16px"> OpenId <td> <a href="https://github.com/rocketlabsdev">RocketLabs Development</a>, <a href="https://github.com/starfishmod">Andrew Mee, <a href="https://github.com/bnoguchi">Brian Noguchi</a>
<tr> <td> LDAP (experimental; not production-tested) <td>
<tr> <td> LDAP / ActiveDirectory <td> <a href="https://github.com/marek-obuchowicz">Marek Obuchowicz</a> from <a href="https://www.korekontrol.eu/">Korekontrol</a>
<tr> <td> Windows Azure Access Control Service (ACS)<td> <a href="https://github.com/darrenzully">Dario Renzulli</a>, <a href="https://github.com/jpgarcia">Juan Pablo Garcia</a>, <a href="https://github.com/woloski">Matias Woloski</a> from <a href="http://blogs.southworks.net/">Southworks</a>
</tbody>
</table>
Expand Down Expand Up @@ -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
Expand Down
59 changes: 49 additions & 10 deletions lib/modules/ldap.js
Original file line number Diff line number Diff line change
@@ -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) {});

;