Skip to content
This repository was archived by the owner on Aug 28, 2023. It is now read-only.

Commit 6e8934e

Browse files
authoredAug 20, 2020
Merge pull request #435 from hsimah/feature/add_proxy_support
#341 add in basic proxy agent
2 parents 6769240 + c03ba97 commit 6e8934e

File tree

4 files changed

+41
-15
lines changed

4 files changed

+41
-15
lines changed
 

‎README.md

+5
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ passport.use(new OIDCStrategy({
6767
cookieSameSite: config.creds.cookieSameSite, // boolean
6868
cookieEncryptionKeys: config.creds.cookieEncryptionKeys,
6969
clockSkew: config.creds.clockSkew,
70+
proxy: { port: 'proxyport', host: 'proxyhost', protocol: 'http' },
7071
},
7172
function(iss, sub, profile, accessToken, refreshToken, done) {
7273
if (!profile.oid) {
@@ -532,6 +533,10 @@ var bearerStrategy = new BearerStrategy(options,
532533

533534
This value is the clock skew (in seconds) allowed in token validation. It must be a positive integer. The default value is 300 seconds.
534535

536+
* `proxy` (optional)
537+
538+
This value is the proxy settings object: { port: 'proxyport', host: 'proxyhost', protocol: 'http' }
539+
535540
##### 4.2.1.3 Verify callback
536541

537542
If you set `passReqToCallback` option to false, you can use the following verify callback

‎lib/metadata.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
const request = require('request');
2727
const async = require('async');
2828
const aadutils = require('./aadutils');
29-
29+
const HttpsProxyAgent = require('https-proxy-agent');
3030
const Log = require('./logging').getLogger;
3131

3232
const log = new Log('AzureAD: Metadata Parser');
@@ -46,6 +46,10 @@ function Metadata(url, authtype, options) {
4646
this.metadata = null;
4747
this.authtype = authtype;
4848
this.loggingNoPII = options.loggingNoPII;
49+
if (options.proxy) {
50+
// if user has specified proxy settings instantiate agent
51+
this.httpsProxyAgent = new HttpsProxyAgent(options.proxy);
52+
}
4953
}
5054

5155
Object.defineProperty(Metadata, 'url', {
@@ -66,6 +70,12 @@ Object.defineProperty(Metadata, 'metadata', {
6670
},
6771
});
6872

73+
Object.defineProperty(Metadata, 'httpsProxyAgent', {
74+
get: function getHttpsProxyAgent() {
75+
return this.httpsProxyAgent;
76+
}
77+
});
78+
6979
Metadata.prototype.updateOidcMetadata = function updateOidcMetadata(doc, next) {
7080
log.info('Request to update the Open ID Connect Metadata');
7181

@@ -93,7 +103,7 @@ Metadata.prototype.updateOidcMetadata = function updateOidcMetadata(doc, next) {
93103
}
94104

95105
// fetch the signing keys
96-
request.get(jwksUri, { json: true }, (err, response, body) => {
106+
request.get({ uri: jwksUri, agent: self.httpsProxyAgent, json: true }, (err, response, body) => {
97107
if (err) {
98108
return next(err);
99109
}
@@ -151,7 +161,7 @@ Metadata.prototype.generateOidcPEM = function generateOidcPEM(kid) {
151161
// generate PEM from `modulus` and `exponent`
152162
pubKey = aadutils.rsaPublicKeyPem(key.n, key.e);
153163
foundKey = true;
154-
164+
155165
return pubKey;
156166
});
157167

@@ -161,14 +171,14 @@ Metadata.prototype.generateOidcPEM = function generateOidcPEM(kid) {
161171
else
162172
throw new Error(`a key with kid %s cannot be found`, kid);
163173
}
164-
174+
165175
if (!pubKey) {
166176
if (self.loggingNoPII)
167177
throw new Error('generating public key pem failed');
168178
else
169179
throw new Error(`generating public key pem failed for kid: %s`, kid);
170180
}
171-
181+
172182
return pubKey;
173183
};
174184

@@ -178,7 +188,7 @@ Metadata.prototype.fetch = function fetch(callback) {
178188
async.waterfall([
179189
// fetch the Federation metadata for the AAD tenant
180190
(next) => {
181-
request.get(self.url, (err, response, body) => {
191+
request.get({ uri: self.url, agent: self.httpsProxyAgent }, (err, response, body) => {
182192
if (err) {
183193
return next(err);
184194
}

‎lib/oidcstrategy.js

+18-8
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const InternalOpenIDError = require('./errors/internalopeniderror');
4949
const Log = require('./logging').getLogger;
5050
const Metadata = require('./metadata').Metadata;
5151
const OAuth2 = require('oauth').OAuth2;
52+
const HttpsProxyAgent = require('https-proxy-agent');
5253
const SessionContentHandler = require('./sessionContentHandler').SessionContentHandler;
5354
const CookieContentHandler = require('./cookieContentHandler').CookieContentHandler;
5455
const Validator = require('./validator').Validator;
@@ -285,6 +286,10 @@ function onProfileLoaded(strategy, args) {
285286
* (2) must be a positive integer
286287
* (3) Description:
287288
* the clock skew (in seconds) allowed in token validation, default value is CLOCK_SKEW
289+
*
290+
* - `proxy` (1) Optional
291+
* (2) Description:
292+
* the configuration parameters for HttpsProxyAgent
288293
*
289294
* Examples:
290295
*
@@ -476,7 +481,7 @@ function Strategy(options, verify) {
476481
/****************************************************************************************
477482
* Take care of scope
478483
***************************************************************************************/
479-
// make scope an array
484+
// make scope an array
480485
if (!options.scope)
481486
options.scope = [];
482487
if (!Array.isArray(options.scope))
@@ -601,9 +606,9 @@ Strategy.prototype.authenticate = function authenticateStrategy(req, options) {
601606
var response = options && options.response || req.res;
602607

603608
// 'params': items we get from the request or metadata, such as id_token, code, policy, metadata, cacheKey, etc
604-
var params = { 'tenantIdOrName': tenantIdOrName, 'extraAuthReqQueryParams': extraAuthReqQueryParams, 'extraTokenReqQueryParams': extraTokenReqQueryParams };
609+
var params = { 'proxy': self._options.proxy, 'tenantIdOrName': tenantIdOrName, 'extraAuthReqQueryParams': extraAuthReqQueryParams, 'extraTokenReqQueryParams': extraTokenReqQueryParams };
605610
// 'oauthConfig': items needed for oauth flow (like redirection, code redemption), such as token_endpoint, userinfo_endpoint, etc
606-
var oauthConfig = { 'resource': resource, 'customState': customState, 'domain_hint': domain_hint, 'login_hint': login_hint, 'prompt': prompt, 'response': response };
611+
var oauthConfig = { 'proxy': self._options.proxy, 'resource': resource, 'customState': customState, 'domain_hint': domain_hint, 'login_hint': login_hint, 'prompt': prompt, 'response': response };
607612
// 'optionsToValidate': items we need to validate id_token against, such as issuer, audience, etc
608613
var optionsToValidate = {};
609614

@@ -672,7 +677,7 @@ Strategy.prototype.authenticate = function authenticateStrategy(req, options) {
672677
* @param {Object} req
673678
* @param {Object} next
674679
*/
675-
Strategy.prototype.collectInfoFromReq = function(params, req, next, response) {
680+
Strategy.prototype.collectInfoFromReq = function (params, req, next, response) {
676681
const self = this;
677682

678683
// the things we will put into 'params':
@@ -858,7 +863,7 @@ Strategy.prototype.setOptions = function setOptions(params, oauthConfig, options
858863
}
859864

860865
// for B2C, verify the endpoints in oauthConfig has the correct policy
861-
if (self._options.isB2C){
866+
if (self._options.isB2C) {
862867
var policyChecker = (endpoint, policy) => {
863868
var u = {};
864869
try {
@@ -956,7 +961,7 @@ Strategy.prototype._idTokenHandler = function idTokenHandler(params, optionsToVa
956961
var decrypted_token;
957962

958963
return jwe.decrypt(id_token, optionsToValidate.jweKeyStore, log, (err, decrypted_token) => {
959-
if(err)
964+
if (err)
960965
return next(err);
961966

962967
params.id_token = decrypted_token;
@@ -1462,7 +1467,7 @@ Strategy.prototype._getAccessTokenBySecretOrAssertion = function getAccessTokenB
14621467
return next(err);
14631468
else
14641469
post_params['client_assertion'] = assertion;
1465-
});
1470+
});
14661471

14671472
if (self._options.loggingNoPII)
14681473
log.info('In _getAccessTokenBySecretOrAssertion: we created a client assertion');
@@ -1480,7 +1485,7 @@ Strategy.prototype._getAccessTokenBySecretOrAssertion = function getAccessTokenB
14801485
var results;
14811486
try {
14821487
results = JSON.parse(data);
1483-
} catch(e) {
1488+
} catch (e) {
14841489
results = querystring.parse(data);
14851490
}
14861491
callback(null, results);
@@ -1519,6 +1524,11 @@ var createOauth2Instance = function(oauthConfig) {
15191524
libraryVersionParameterName : libraryVersion} // customHeaders
15201525
);
15211526

1527+
if (oauthConfig.proxy) {
1528+
// if user has specified proxy settings instantiate agent
1529+
oauth2.setAgent(new HttpsProxyAgent(oauthConfig.proxy));
1530+
}
1531+
15221532
return oauth2;
15231533
};
15241534

‎package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@
3636
"base64url": "^3.0.0",
3737
"bunyan": "^1.8.0",
3838
"cache-manager": "2.10.2",
39+
"https-proxy-agent": "^2.2.2",
3940
"jws": "^3.1.3",
4041
"jwk-to-pem": "^1.2.6",
4142
"lodash": "^4.11.2",
42-
"oauth": "0.9.14",
43+
"oauth": "0.9.15",
4344
"passport": "^0.3.2",
4445
"request": "^2.72.0",
4546
"valid-url": "^1.0.6"

0 commit comments

Comments
 (0)
This repository has been archived.