Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Proxy authentication added.

  • Loading branch information...
commit 18a5e0234de24bb421bec9a538b391c1c4ce72a5 1 parent 3cbe3a5
@gevorg authored
View
5 README.md
@@ -82,7 +82,8 @@ app.get('/', function(req, res) {
*/
var basic = auth({
authRealm : "Private area.",
- authList : ['mia:supergirl', 'Carlos:test456', 'Sam:oho']
+ authList : ['mia:supergirl', 'Carlos:test456', 'Sam:oho'],
+ proxy : true
});
/**
@@ -112,7 +113,7 @@ http.createServer(function(req, res) {
- `authList` - List where user details are stored in format **{user:pass}** or **{user:passHash}** for basic access and **{user:realm:passHash}** for digest access, ignored if `authFile` is specified.
- `authType` - Type of authentication, may be **basic** or **digest**, optional, default is **basic**.
- `algorithm` - Algorithm that will be used for authentication, may be **MD5** or **MD5-sess**, optional, default is **MD5**. Only for **digest** `authType`.
-
+ - `proxy` - Identifies if authentication is done for proxy or not, optional, default is **false**.
## Running tests
It uses [nodeunit](https://github.com/caolan/nodeunit/), so just run following command in package directory:
View
38 examples/example_digest_helper.js
@@ -0,0 +1,38 @@
+/**
+ * HTTP authentication module.
+ */
+var auth = require('../lib/http-auth');
+
+/**
+ * HTTP module.
+ */
+var http = require('http');
+
+/**
+ * Requesting new authentication instance.
+ */
+var digest = auth({
+ authRealm : "Private area.",
+ // username is mia, password is supergirl.
+ authHelper : function(user, callback) {
+ if ( user === 'mia' ) {
+ callback('mia:Private area.:3a556dc7260e8e7f032d247fb668b06b');
+ } else {
+ callback();
+ }
+ },
+ authType : 'digest'
+});
+
+/**
+ * Creating new HTTP server.
+ */
+http.createServer(function(req, res) {
+ // Apply authentication to server.
+ digest.apply(req, res, function(username) {
+ res.end("Welcome to private area - " + username + "!");
+ });
+}).listen(1337);
+
+// Log url.
+console.log("Server running at http://127.0.0.1:1337/");
View
5 examples/example_proxy.js
@@ -19,7 +19,8 @@ var httpProxy = require('http-proxy');
*/
var basic = auth({
authRealm : "Private area.",
- authList : ['mia:supergirl', 'Carlos:test456', 'Sam:oho']
+ authList : ['mia:supergirl', 'Carlos:test456', 'Sam:oho'],
+ proxy : true
});
/**
@@ -42,4 +43,4 @@ http.createServer(function(req, res) {
}).listen(9000);
// Log url.
-console.log("Server running at http://127.0.0.1:8000/");
+console.log("Server running at http://127.0.0.1:8000/");
View
25 lib/auth/basic.js
@@ -23,14 +23,18 @@ module.exports = Basic;
*
* @param {String} authRealm authentication realm.
* @param {Array} authUsers array of users.
+ * @param {Function} authHelper authentication helper for custom authentication mechanism.
+ * @param {Boolean} proxy identifies if authentication is used for proxy.
*/
-function Basic(authRealm, authUsers, authHelper) {
+function Basic(authRealm, authUsers, authHelper, proxy) {
// Realm.
this.realm = authRealm;
// Users.
this.users = authUsers;
// Authentication helper.
this.authHelper = authHelper;
+ // Proxy or not.
+ this.proxy = proxy;
// Used for async callback.
var self = this;
@@ -65,9 +69,10 @@ Basic.prototype.isAuthenticated = function(request, callback) {
// If header exists.
var authHeader = null;
- if ("authorization" in request.headers) {
+
+ if (!this.proxy) {
authHeader = request.headers["authorization"];
- } else if ("proxy-authorization" in request.headers) {
+ } else {
authHeader = request.headers["proxy-authorization"];
}
@@ -139,8 +144,14 @@ Basic.prototype.validateClientString = function(clientUserName, clientPasswordHa
*/
Basic.prototype.ask = function(response) {
var header = "Basic realm=\"" + this.realm + "\"";
-
- response.setHeader("WWW-Authenticate", header);
- response.writeHead(401);
- response.end(defaults.HTML_401);
+
+ if (this.proxy) {
+ response.setHeader("Proxy-Authenticate", header);
+ response.writeHead(407);
+ response.end(defaults.HTML_407);
+ } else {
+ response.setHeader("WWW-Authenticate", header);
+ response.writeHead(401);
+ response.end(defaults.HTML_401);
+ }
};
View
21 lib/auth/digest.js
@@ -32,8 +32,9 @@ function State(name){
* @param {Array} authUsers array of users.
* @param {String} algorithm algorithm for authentication.
* @param {Function} authentication helper allows to override standard authentication.
+ * @param {Boolean} proxy identifies if authentication is for proxy.
*/
-function Digest(authRealm, authUsers, algorithm, authHelper) {
+function Digest(authRealm, authUsers, algorithm, authHelper, proxy) {
// Realm.
this.realm = authRealm;
// Users.
@@ -44,6 +45,8 @@ function Digest(authRealm, authUsers, algorithm, authHelper) {
this.algorithm = algorithm;
// Authentication helper.
this.authHelper = authHelper;
+ // Authentication proxy.
+ this.proxy = proxy;
// Used for async callback.
var self = this;
@@ -82,9 +85,9 @@ Digest.prototype.isAuthenticated = function(request, callback) {
// If header exists.
var authHeader = null;
- if ("authorization" in request.headers) {
+ if (!this.proxy) {
authHeader = request.headers["authorization"];
- } else if ("proxy-authorization" in request.headers) {
+ } else {
authHeader = request.headers["proxy-authorization"];
}
@@ -183,9 +186,15 @@ Digest.prototype.ask = function(response, stale) {
var header = "Digest realm=\"" + this.realm + "\", qop=\"auth\", nonce=\"" + nonce +
"\", algorithm=\"" + this.algorithm + "\", stale=\"" + (stale ? true : false) + "\"";
- response.setHeader("WWW-Authenticate", header);
- response.writeHead(401);
- response.end(defaults.HTML_401);
+ if (this.proxy) {
+ response.setHeader("Proxy-Authenticate", header);
+ response.writeHead(407);
+ response.end(defaults.HTML_407);
+ } else {
+ response.setHeader("WWW-Authenticate", header);
+ response.writeHead(401);
+ response.end(defaults.HTML_401);
+ }
};
/**
* Method for clearing not used nonces.
View
9 lib/defaults.js
@@ -2,11 +2,14 @@
* Module for default setups.
*/
module.exports = {
+ /**
+ * Default HTML for not authorized proxy page.
+ */
+ 'HTML_407' : "<!DOCTYPE html>\n<html><head><title>407 Proxy authentication required</title></head><body><h1>407 Proxy authentication required</h1><p>This page requires authorization.</p></body></html>",
/**
* Default HTML for not authorized page.
*/
- 'HTML_401' : "<!DOCTYPE html>\n<html><head><title>401 Unauthorized</title></head><body><h1>401 "
- + "Unauthorized</h1><p>This page requires authorization.</p></body></html>",
+ 'HTML_401' : "<!DOCTYPE html>\n<html><head><title>401 Unauthorized</title></head><body><h1>401 Unauthorized</h1><p>This page requires authorization.</p></body></html>",
/**
* Nonce expire timeout.
*/
@@ -15,4 +18,4 @@ module.exports = {
* Default algorithm for Digest Access Authentication.
*/
'DEFAULT_ALGO' : 'MD5'
-};
+};
View
1  lib/http-auth.js
@@ -21,6 +21,7 @@ var opt = require('./options');
* ignored if authFile is specified.
* - authType type of authentication, digest | basic, optional, default is basic.
* - algorithm algorithm that will be used, may be MD5 or MD5-sess, optional, default is MD5.
+ * - proxy identifies if authentication is done for proxy, optional, default is false.
* @return {Object} authentication instance.
*/
module.exports = function(options) {
View
7 lib/options.js
@@ -14,7 +14,12 @@ module.exports = function(options) {
if(!options) {
throw new Error("Authentication options are empty!");
}
-
+
+ // Checking for proxy.
+ if(!options.proxy) {
+ options['proxy'] = false;
+ }
+
// Checking authType.
var authType = options['authType'];
if(!authType) {
View
4 lib/provider.js
@@ -15,9 +15,9 @@ module.exports = {
*/
'newInstance' : function(options) {
if(options && options.authType == 'digest') {
- return new Digest(options.authRealm, options.authUsers, options.algorithm, options.authHelper);
+ return new Digest(options.authRealm, options.authUsers, options.algorithm, options.authHelper, options.proxy);
} else if(options && options.authType == 'basic') {
- return new Basic(options.authRealm, options.authUsers, options.authHelper);
+ return new Basic(options.authRealm, options.authUsers, options.authHelper, options.proxy);
} else {
throw new Error("Invalid type, may be digest | basic!");
}
View
2  package.json
@@ -1,7 +1,7 @@
{
"name": "http-auth",
"description": "Node.js package for HTTP basic and digest access authentication.",
- "version": "1.2.6",
+ "version": "1.2.7",
"author": "Gevorg Harutyunyan (http://github.com/gevorg)",
"maintainers": [
{

2 comments on commit 18a5e02

@escribileamauro

I see that you are including the changes to respond with 407 ! that's great :)

@gevorg
Owner

Thanks to you Mauro, I have published it to NPM. The only change is that you need to do provide proxy:true option. Let me know if it does not work for you. Gevorg.

Please sign in to comment.
Something went wrong with that request. Please try again.