Skip to content

Commit 72fa04b

Browse files
authored
Merge pull request #93 from jsfi/master
Support usage behind a proxy if the application can distinguish its user
2 parents 89fee6a + 3e8e581 commit 72fa04b

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@ It's not recommended, but it's possible to add NTLM-Authentication without valid
9898
| `domaincontroller` | `null` / `string` / `array` | `null` | One or more domaincontroller(s) to handle the authentication. If `null` is specified the user is not validated. Active Directory is supported. |
9999
| `tlsOptions` | `object` | `undefined` | An options object that will be passed to [tls.connect](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback) and [tls.createSecureContext](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options). __Only required when using ldaps and the server's certificate is signed by a certificate authority not in Node's default list of CAs.__ (or use [NODE_EXTRA_CA_CERTS](https://nodejs.org/api/cli.html#cli_node_extra_ca_certs_file) environment variable)|
100100
| `tlsOptions.ca` | `string` / `array` / `Buffer` | `undefined` | Override the trusted CA certificates provided by Node. Refer to [tls.createSecureContext](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) |
101-
| `getConnectionId` | `function` | `function(request, response) { return utils.uuidv4(); }` | Function to generate custom connection IDs, based optionally on the request and response objects. |
101+
| `getConnectionId` | `function` | `function(request, response) { return utils.uuidv4(); }` | Function to generate custom connection IDs, based optionally on the request and response objects. Used by the default implementation of `getProxyId` to keep backwards compatibility. *deprecated* |
102+
| `getProxyId` | `function` | `function(request, response) { if (!request.connection.id) { request.connection.id = options.getConnectionId(request, response); } return request.connection.id; }` | Function to generate custom proxy cache IDs, based optionally on the request and response objects. |
103+
| `getCachedUserData` | `function` | `function(request, response) { return request.connection.ntlm; }` | Function to return the cached NTLM user data. |
104+
| `addCachedUserData` | `function` | `function(request, response, userData) { request.connection.ntlm = userData; }` | Function to cache the NTLM user data. |
102105

103106
## logging (examples)
104107
<a name="logging" />

lib/express-ntlm.js

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,21 @@ module.exports = function(options) {
4343

4444
getConnectionId(request, response) {
4545
return utils.uuidv4();
46+
},
47+
48+
getProxyId(request, response) {
49+
if (!request.connection.id) {
50+
request.connection.id = options.getConnectionId(request, response);
51+
}
52+
53+
return request.connection.id;
54+
},
55+
56+
getCachedUserData(request, response) {
57+
return request.connection.ntlm;
58+
},
59+
addCachedUserData(request, response, userData) {
60+
request.connection.ntlm = userData;
4661
}
4762
}, options);
4863

@@ -137,7 +152,9 @@ module.exports = function(options) {
137152
}
138153

139154
function handle_type1(request, response, next, ntlm_message, callback) {
140-
cache.remove(request.connection.id);
155+
var proxyId = options.getProxyId(request, response);
156+
157+
cache.remove(proxyId);
141158
cache.clean();
142159

143160
connect_to_proxy(ntlm_message, function(error, proxy, challenge) {
@@ -147,14 +164,15 @@ module.exports = function(options) {
147164
response.setHeader('WWW-Authenticate', 'NTLM ' + challenge.toString('base64'));
148165
response.end();
149166

150-
cache.add(request.connection.id, proxy);
167+
cache.add(proxyId, proxy);
151168

152169
return callback();
153170
});
154171
}
155172

156173
function handle_type3(request, response, next, ntlm_message, callback) {
157-
var proxy = cache.get_proxy(request.connection.id);
174+
var proxyId = options.getProxyId(request, response),
175+
proxy = cache.get_proxy(proxyId);
158176

159177
var userDomainWorkstation = parse_ntlm_authenticate(ntlm_message),
160178
user = userDomainWorkstation[0],
@@ -176,10 +194,10 @@ module.exports = function(options) {
176194

177195
request.ntlm = userData;
178196
response.locals.ntlm = userData;
179-
request.connection.ntlm = userData;
197+
options.addCachedUserData(request, response, userData);
180198

181199
if (!result) {
182-
cache.remove(request.connection.id);
200+
cache.remove(proxyId);
183201
options.debug(options.prefix, 'User ' + domain + '/' + user + ' authentication for URI ' + request.protocol + '://' + request.get('host') + request.originalUrl);
184202
return options.forbidden(request, response, next);
185203
} else {
@@ -190,13 +208,9 @@ module.exports = function(options) {
190208
}
191209

192210
return function(request, response, next) {
193-
if (!request.connection.id) {
194-
request.connection.id = options.getConnectionId(request, response);
195-
}
196-
197211
var auth_headers = request.headers.authorization;
198212

199-
var user = request.connection.ntlm;
213+
var user = options.getCachedUserData(request, response);
200214
if (user && user.Authenticated) {
201215
options.debug(options.prefix, 'Connection already authenticated ' + user.DomainName + '/' + user.UserName);
202216
if (auth_headers) {
@@ -241,7 +255,7 @@ module.exports = function(options) {
241255
}
242256

243257
if (ntlm_version === 3) {
244-
if (cache.get_proxy(request.connection.id) !== null) {
258+
if (cache.get_proxy(options.getProxyId(request, response)) !== null) {
245259
return handle_type3(request, response, next, ah_data[1], function(error) {
246260
if (error) {
247261
options.debug(options.prefix, error.stack);

0 commit comments

Comments
 (0)