passport-ldapauth
Advanced tools
Comparing version 0.3.0 to 0.3.1
## Changes | ||
* v0.3.1 | ||
* [#35](https://github.com/vesse/passport-ldapauth/issues/35) - Show more specific error messages from Microsoft AD login errors if identified. | ||
* v0.3.0 | ||
@@ -4,0 +6,0 @@ * [#10](https://github.com/vesse/passport-ldapauth/issues/10) - Add support for fetching groups. While this is really coming from [ldapauth-fork](https://github.com/vesse/node-ldapauth-fork), updated the minor version of this library as well to draw attention to new features. |
@@ -140,9 +140,34 @@ "use strict"; | ||
/** | ||
* AD possible messages | ||
* http://www-01.ibm.com/support/docview.wss?uid=swg21290631 | ||
*/ | ||
var messages = { | ||
'530': options.invalidLogonHours || 'Not Permitted to login at this time', | ||
'531': options.invalidWorkstation || 'Not permited to logon at this workstation', | ||
'532': options.passwordExpired || 'Password expired', | ||
'533': options.accountDisabled || 'Account disabled', | ||
'534': options.accountDisabled || 'Account disabled', | ||
'701': options.accountExpired || 'Account expired', | ||
'773': options.passwordMustChange || 'User must reset password', | ||
'775': options.accountLockedOut || 'User account locked', | ||
default: options.invalidCredentials || 'Invalid username/password' | ||
}; | ||
ldap = new LdapAuth(this.options.server); | ||
ldap.authenticate(username, password, function(err, user) { | ||
ldap.close(function(){}); // We don't care about the closing | ||
if (err) { | ||
// Invalid credentials / user not found are not errors but login failures | ||
if (err.name === 'InvalidCredentialsError' || err.name === 'NoSuchObjectError' || (typeof err === 'string' && err.match(/no such user/i))) { | ||
return this.fail({message: options.invalidCredentials || 'Invalid username/password'}, 401); | ||
var message = options.invalidCredentials || 'Invalid username/password'; | ||
if(err.message) { | ||
var ldapComment = err.message.match(/data ([0-9a-fA-F]*), v[0-9a-fA-F]*/); | ||
if(ldapComment && ldapComment[1]){ | ||
message = messages[ldapComment[1]] || messages['default']; | ||
} | ||
} | ||
return this.fail({message: message}, 401); | ||
} | ||
@@ -149,0 +174,0 @@ if (err.name === 'ConstraintViolationError'){ |
@@ -9,3 +9,4 @@ { | ||
"Jason Gelinas <jason.gelinas@citi.com>", | ||
"arumi <arumi@wge7033.secheron.net>" | ||
"arumi <arumi@wge7033.secheron.net>", | ||
"Anthony Hernandez <anthony.hernandez@clownphobia.com>" | ||
], | ||
@@ -18,3 +19,3 @@ "keywords": [ | ||
], | ||
"version": "0.3.0", | ||
"version": "0.3.1", | ||
"license": { | ||
@@ -40,9 +41,10 @@ "type": "MIT", | ||
"devDependencies": { | ||
"body-parser": "1.12.x", | ||
"chai": "2.1.x", | ||
"body-parser": "1.14.x", | ||
"chai": "3.3.x", | ||
"express": "4.9.x", | ||
"express-session": "1.11.x", | ||
"ldapjs": "0.7.x", | ||
"mocha": "2.1.x", | ||
"supertest": "0.15.x", | ||
"passport": "~0.2.0" | ||
"mocha": "2.3.x", | ||
"passport": "0.3.x", | ||
"supertest": "1.1.x" | ||
}, | ||
@@ -49,0 +51,0 @@ "scripts": { |
@@ -5,2 +5,27 @@ # passport-ldapauth | ||
## Node v0.12 | ||
### `dtrace-provider` issue | ||
Currently the latest released version of [ldapjs](https://github.com/mcavage/node-ldapjs) which this module depends on does not install succesfully on Node v0.12 on Mac (see [issue #258](https://github.com/mcavage/node-ldapjs/issues/258)) due to old `dtrace-provider` dependency. To work around the issue, add dependency to `ldapjs` master to your `package.json`: | ||
```json | ||
{ | ||
"dependencies": { | ||
"ldapjs": "mcavage/node-ldapjs", | ||
"passport-ldapauth": "0.3.0" | ||
} | ||
} | ||
``` | ||
`dtrace-provider` is an optional dependency, ie. if you don't need it there's no need to do anything. | ||
### SSL issue | ||
This also comes form `ldapjs` (see [issue #258](https://github.com/mcavage/node-ldapjs/issues/258)), and the same workaround solves it. | ||
### Microsoft AD LDAP protocol | ||
Error 49 handles much more than just Invalid credentials, partial support for MS AD LDAP has been implemented (see [issue #35](https://github.com/vesse/passport-ldapauth/issues/35)). Any additional supported data/comments could be added in the future. | ||
## Install | ||
@@ -58,9 +83,19 @@ | ||
In addition to [default authentication options](http://passportjs.org/guide/authenticate/) the following options are available for `passport.authenticate()`: | ||
In addition to [default authentication options](http://passportjs.org/guide/authenticate/) the following flash message options are available for `passport.authenticate()`: | ||
* `badRequestMessage` flash message for missing username/password (default: 'Missing credentials') | ||
* `invalidCredentials` flash message for `InvalidCredentialsError`, `NoSuchObjectError`, and `/no such user/i` LDAP errors (default: 'Invalid username/password') | ||
* `userNotFound` flash message when LDAP returns no error but also no user (default: 'Invalid username/password') | ||
* `constraintViolation` flash message when user account is locked (default: 'Exceeded password retry limit, account locked') | ||
* `badRequestMessage`: missing username/password (default: 'Missing credentials') | ||
* `invalidCredentials`: `InvalidCredentialsError`, `NoSuchObjectError`, and `/no such user/i` LDAP errors (default: 'Invalid username/password') | ||
* `userNotFound`: LDAP returns no error but also no user (default: 'Invalid username/password') | ||
* `constraintViolation`: user account is locked (default: 'Exceeded password retry limit, account locked') | ||
And for [Microsoft AD messages](http://www-01.ibm.com/support/docview.wss?uid=swg21290631), these flash message options can also be used (used instead of `invalidCredentials` if matching error code is found): | ||
* `invalidLogonHours`: not being allowed to login at this current time (default: 'Not Permitted to login at this time') | ||
* `invalidWorkstation`: not being allowed to login from this current location (default: 'Not permited to logon at this workstation') | ||
* `passwordExpired`: expired password (default: 'Password expired') | ||
* `accountDisabled`: disabled account (default: 'Account disabled') | ||
* `accountExpired`: expired account (default: 'Account expired') | ||
* `passwordMustChange`: password change (default: 'User must reset password') | ||
* `accountLockedOut`: locked out account (default: 'User account locked') | ||
## Express example | ||
@@ -127,3 +162,3 @@ | ||
Instead of providing a static configuration object, you can pass a function as `options` that will take care of fetching the configuration. It will be called with the and a callback function having the standard `(err, result)` signature. Notice that the provided function will be called on every authenticate request. | ||
Instead of providing a static configuration object, you can pass a function as `options` that will take care of fetching the configuration. It will be called with the `req` object and a callback function having the standard `(err, result)` signature. Notice that the provided function will be called on every authenticate request. | ||
@@ -130,0 +165,0 @@ ```javascript |
var express = require('express'), | ||
passport = require('passport'), | ||
LdapStrategy = require('passport-ldapauth').Strategy, | ||
bodyParser = require('body-parser'); | ||
bodyParser = require('body-parser'), | ||
session = require('express-session'); | ||
@@ -18,2 +19,10 @@ var server = null; | ||
passport.serializeUser(function(user, cb) { | ||
cb(null, user.dn); | ||
}); | ||
passport.deserializeUser(function(dn, cb) { | ||
cb(null, {dn: dn}); | ||
}); | ||
exports.start = function(opts, testopts, cb) { | ||
@@ -26,3 +35,9 @@ | ||
app.use(bodyParser.json()); | ||
app.use(session({ | ||
secret: 'cat', | ||
saveUninitialized: false, | ||
resave: false | ||
})); | ||
app.use(passport.initialize()); | ||
app.use(passport.session()); | ||
@@ -33,2 +48,13 @@ app.post('/login', passport.authenticate('ldapauth', {session: false}), function(req, res) { | ||
app.post('/custom-cb-login', function(req, res, next) { | ||
passport.authenticate('ldapauth', function(err, user, info) { | ||
if (err) return next(err); | ||
if (!user) return res.status(401).send(info); | ||
req.logIn(user, function(err) { | ||
if (err) return next(err); | ||
return res.json(user); | ||
}) | ||
})(req, res, next); | ||
}); | ||
if (typeof cb === 'function') return cb(app); | ||
@@ -35,0 +61,0 @@ return; |
@@ -48,2 +48,4 @@ var ldap = require('ldapjs'); | ||
res.send(db['valid']); | ||
} else if (req.filter.attribute === 'uid' && req.filter.value === 'ms-ad') { | ||
return next(new ldap.InvalidCredentialsError("0090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 533, v893 HEX: 0x533 - account disabled")); | ||
} else if (req.filter.attribute === 'member' && req.filter.value === db.valid.dn) { | ||
@@ -50,0 +52,0 @@ res.send({ |
@@ -124,3 +124,3 @@ var should = require('chai').Should(), | ||
.post('/login') | ||
.send({username: 'valid', password: 'invvalid'}) | ||
.send({username: 'valid', password: 'invalid'}) | ||
.expect(401) | ||
@@ -133,6 +133,18 @@ .end(cb); | ||
.post('/login') | ||
.send({username: 'nonexisting', password: 'invvalid'}) | ||
.send({username: 'nonexisting', password: 'invalid'}) | ||
.expect(401) | ||
.end(cb); | ||
}); | ||
it("should return more specific flash message for AD reply", function(cb) { | ||
request(expressapp) | ||
.post('/custom-cb-login') | ||
.send({username: 'ms-ad', password: 'invalid'}) | ||
.expect(401) | ||
.end(function(err, res) { | ||
should.not.exist(err); | ||
res.body.message.should.equal('Account disabled') | ||
cb(err, res); | ||
}); | ||
}); | ||
}); | ||
@@ -139,0 +151,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
32535
599
193
8