diff --git a/CHANGES.md b/CHANGES.md
index b99f770..563c9b2 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,7 @@
## Changes
+* v0.6.0
+ * Added option `credentialsLookup` that can be used eg. to add Basic Auth header parsing support.
* v0.5.0
* Updated deps. ldapauth-fork update changes bind credentials handling to work better with falsy values needed in anonymous bind.
* v0.4.0
diff --git a/README.md b/README.md
index 7f8e802..28f7140 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,7 @@ passport.use(new LdapStrategy({
* `tlsOptions`: Optional object with options accepted by Node.js [tls](http://nodejs.org/api/tls.html#tls_tls_connect_options_callback) module.
* `usernameField`: Field name where the username is found, defaults to _username_
* `passwordField`: Field name where the password is found, defaults to _password_
+* `creadentialsLookup`: Optional, synchronous function that provides the login credentials from `req`. See [below](#credentials-lookup) for more.
* `passReqToCallback`: When `true`, `req` is the first argument to the verify callback (default: `false`):
passport.use(new LdapStrategy(..., function(req, user, done) {
@@ -132,6 +133,18 @@ var opts = {
};
...
```
+
+## `credentialsLookup`
+
+A synchronous function that receives the `req` object and returns an objec with keys `username` and `password` (or `name` and `pass`) can be provided. Note, that when this is provided the default lookup is not performed. This can be used to eg. enable basic auth header support:
+
+```javascript
+var basicAuth = require('basic-auth');
+var ldapOpts = {
+ server: { ... },
+ credentialsLookup: basicAuth
+}
+```
## Asynchronous configuration retrieval
diff --git a/lib/passport-ldapauth/strategy.js b/lib/passport-ldapauth/strategy.js
index de7872f..faec28e 100644
--- a/lib/passport-ldapauth/strategy.js
+++ b/lib/passport-ldapauth/strategy.js
@@ -130,8 +130,18 @@ var handleAuthentication = function(req, options) {
var username, password, ldap;
options || (options = {});
- username = lookup(req.body, this.options.usernameField) || lookup(req.query, this.options.usernameField);
- password = lookup(req.body, this.options.passwordField) || lookup(req.query, this.options.passwordField);
+ if (typeof this.options.credentialsLookup === 'function') {
+ var credentials = this.options.credentialsLookup(req);
+ if (credentials != null) {
+ // name and pass as a courtesy for those who use basic-auth directly as
+ // they're likely the main user group.
+ username = credentials.username || credentials.name;
+ password = credentials.password || credentials.pass;
+ }
+ } else {
+ username = lookup(req.body, this.options.usernameField) || lookup(req.query, this.options.usernameField);
+ password = lookup(req.body, this.options.passwordField) || lookup(req.query, this.options.passwordField);
+ }
if (!username || !password) {
return this.fail({message: options.badRequestMessage || 'Missing credentials'}, 400);
@@ -199,12 +209,14 @@ Strategy.prototype.authenticate = function(req, options) {
if ((typeof this.options === 'object') && (!this.getOptions)) {
return handleAuthentication.call(this, req, options);
}
+
var callback = function(err, configuration) {
if (err) return this.fail(err);
this.options = setDefaults(configuration);
handleAuthentication.call(this, req, options);
};
+
// Added functionality: getOptions can accept now up to 2 parameters
if (this.getOptions.length ===1) { // Accepts 1 parameter, backwards compatibility
this.getOptions(callback.bind(this));
diff --git a/package.json b/package.json
index 76e47bd..d2bb6f3 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,7 @@
"ldapauth-fork": "~2.5.0"
},
"devDependencies": {
+ "basic-auth": "1.0.x",
"body-parser": "1.15.x",
"chai": "3.5.x",
"express": "4.14.x",
diff --git a/test/strategy-test.js b/test/strategy-test.js
index 957156d..f925143 100644
--- a/test/strategy-test.js
+++ b/test/strategy-test.js
@@ -1,6 +1,7 @@
var should = require('chai').Should(),
LdapStrategy = require('passport-ldapauth'),
request = require('supertest'),
+ basicAuth = require('basic-auth'),
ldapserver = require('./ldapserver'),
appserver = require('./appserver');
@@ -208,6 +209,19 @@ describe("LDAP authentication strategy", function() {
s.authenticate(req);
});
});
+
+ it("should allow access with valid credentials in the header", function(cb) {
+ var OPTS = JSON.parse(JSON.stringify(BASE_OPTS));
+ OPTS.credentialsLookup = basicAuth;
+
+ start_servers(OPTS, BASE_TEST_OPTS)(function() {
+ request(expressapp)
+ .post('/login')
+ .set('Authorization', 'Basic dmFsaWQ6dmFsaWQ=')
+ .expect(200)
+ .end(cb);
+ });
+ });
});
describe("with options as function", function() {