From 11257a92e7742c86a9359d936744e7daed0100c6 Mon Sep 17 00:00:00 2001 From: Eran Hammer Date: Thu, 14 Nov 2013 22:33:46 -0800 Subject: [PATCH] Allow basic auth without username. closes #1140 --- docs/Reference.md | 7 ++++--- lib/auth/basic.js | 2 +- test/integration/auth.js | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/docs/Reference.md b/docs/Reference.md index 176b2c0c7..2def0c65e 100755 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -992,10 +992,10 @@ Registers an authentication strategy where: ##### Basic authentication -Basic authentication requires validating a username and password combination. The `'basic'` scheme takes the following required options: +Basic authentication requires validating a username and password combination. The `'basic'` scheme takes the following options: -- `scheme` - set to `'basic'`. -- `validateFunc` - a user lookup and password validation function with the signature `function(username, password, callback)` where: +- `scheme` - (required) set to `'basic'`. +- `validateFunc` - (required) a user lookup and password validation function with the signature `function(username, password, callback)` where: - `username` - the username received from the client. - `password` - the password received from the client. - `callback` - a callback function with the signature `function(err, isValid, credentials)` where: @@ -1004,6 +1004,7 @@ Basic authentication requires validating a username and password combination. Th - `credentials` - a credentials object passed back to the application in `request.auth.credentials`. Typically, `credentials` are only included when `isValid` is `true`, but there are cases when the application needs to know who tried to authenticate even when it fails (e.g. with authentication mode `'try'`). +- `allowEmptyUsername` - (optional) if `true`, allows making requests with an empty username. Defaults to `false`. ```javascript var Bcrypt = require('bcrypt'); diff --git a/lib/auth/basic.js b/lib/auth/basic.js index b9c6370fc..f941cb959 100755 --- a/lib/auth/basic.js +++ b/lib/auth/basic.js @@ -55,7 +55,7 @@ internals.Scheme.prototype.authenticate = function (request, callback) { var username = credentialsParts[0]; var password = credentialsParts[1]; - if (!username) { + if (!username && !this.settings.allowEmptyUsername) { return callback(Boom.badRequest('HTTP authentication header missing username', 'Basic')); } diff --git a/test/integration/auth.js b/test/integration/auth.js index 1e1901609..cbd5ba4fb 100755 --- a/test/integration/auth.js +++ b/test/integration/auth.js @@ -195,6 +195,26 @@ describe('Auth', function () { }); }); + it('allow missing username', function (done) { + + var config = { + auth: { + scheme: 'basic', + validateFunc: function (username, password, callback) { callback(null, true, {}); }, + allowEmptyUsername: true + } + }; + + var server1 = new Hapi.Server(config); + server1.route({ method: 'GET', path: '/', handler: function () { this.reply('ok'); }, config: { auth: true } }); + + server1.inject({ method: 'GET', url: '/', headers: { authorization: basicHeader('', 'abcd') } }, function (res) { + + expect(res.statusCode).to.equal(200); + done(); + }); + }); + it('returns an error on unknown user', function (done) { var request = { method: 'POST', url: '/basic', headers: { authorization: basicHeader('doe', '12345') } };