Nodejs Passport Oauth2 Proxy

2019-06-14 13:09发布

问题:

I built my own strategy for passport. Now an instance of my application runs behind a corporate firewall. Thus I need to get all outgoing requests passed to a proxy server first (http), which then connects to the outside world (https). I got this running with other modules like request which offer an option to pass a proxy config.

`app -(http)-> proxy -(https via vpn tunnel)-> www``

Question

1) How can I force the outgoing requests from my passport strategy to go via the proxy?

2) If it is not possible, to just add the option for passport: How can I get all outgoing requests to use the proxy?

I noticed there is a proxy option in the strategy: https://github.com/jaredhanson/passport-oauth2/blob/master/lib/strategy.js#l110

I tried to extend my strategy and pass this option, but it was not successful.

e.g

Strategy = (options, verify) ->
  options = options or {}
  options.authorizationURL = options.authorizationURL or 'https://mywebsite.com/oauth2/authorize'
  options.tokenURL = options.tokenURL or 'https://mywebsite.com/extern/oauth2/auth_form.aspx' 
  options.scopeSeparator = options.scopeSeparator or ','
  options.proxy = options.proxy or process.env['HTTP_PROXY']

回答1:

I could solve the problem finally for all outgoing requests:

Code

inspect = require('eyespect').inspector({maxLength: null})
chalk = require('chalk')

url = require('url')
http = require('http')
https = require('https')

setupHttpProxy = ()->
  proxyHttp = url.parse(process.env['HTTP_PROXY'])
  # console.log chalk.bgRed "proxyHttp"
  # inspect proxyHttp
  http.globalAgent.options.host = proxyHttp.hostname
  http.globalAgent.options.port = proxyHttp.port
  # console.log chalk.bgRed "proxyAgent"
  # inspect http.globalAgent
  return

setupHttpsProxy = ()->
  proxyHttps = url.parse(process.env['HTTPS_PROXY'])
  # console.log chalk.bgRed "proxyHttps"
  # inspect proxyHttps
  https.globalAgent.options.host = proxyHttps.hostname
  https.globalAgent.options.port = proxyHttps.port
  # console.log chalk.bgRed "proxyAgent"
  # inspect https.globalAgent
  return

module.exports = ()->
  setupHttpProxy() if process.env['HTTP_PROXY']?
  setupHttpsProxy() if process.env['HTTPS_PROXY']?
  return

I extended the global agent which is used as the default setting for all outgoing connections.

Information

https://nodejs.org/api/http.html#http_http_globalagent

Own Proxy for Debugging (JS to easy modify/restart with gulp-nodemon)

var inspect = require('eyespect').inspector({maxLength: null});
var chalk = require('chalk');

var express = require('express');
var http = require('http');
var https = require('https');
var fs = require('fs');
var httpProxy = require('http-proxy');
var url = require('url');
var app = express();

//////// OTHER & HELPER ///////////
console.reset = function () {
  return process.stdout.write('\033c');
}

process.on('uncaughtException', function (err) {
    console.log(err);
});


//////// EXPRESS /////////
app.get('*', function (req, res) {
  console.log("req.path", req.path);
  res.send('Hello World!');
});

//////// PROXY SERVER ///////////

        var inspect = require('eyespect').inspector({maxLength: null});
var chalk = require('chalk');

var express = require('express');
var http = require('http');
var https = require('https');
var fs = require('fs');
var httpProxy = require('http-proxy');
var url = require('url');

//////// OTHER & HELPER ///////////
console.reset = function () {
  return process.stdout.write('\033c');
}

process.on('uncaughtException', function (err) {
    console.log(err);
});

//////// PROXY SERVER ///////////
var counter = 1;
proxy = httpProxy.createProxyServer();
http.createServer(function (req, res) {
  counter++;
  console.reset();
  console.log(chalk.bgGreen("\n\n\n\n---------------------------------------"+counter+"---------------------------------------------\n\n"));
  console.log(chalk.bgGreen("PRE HEADER"));
  inspect(req.headers);
  console.log(chalk.bgGreen("SECURITY"));
  inspect(req.secure);
  inspect(req.connection.encrypted);
  console.log(chalk.bgGreen("PRE URL"));
  inspect(req.url);
  console.log(chalk.bgGreen("PRE TARGET"));
  target = 'http://' + req.headers.host;
  // target = 'https://' + req.headers.host;
  inspect(target);

  proxy.proxyRequest(req, res, {
    target: target,
    enable : { xforward: true }
  });

}).listen(7000);

var counterHTTPS = 1;
proxyHTTPS = httpProxy.createProxyServer();

sslOptions = {
  key: fs.readFileSync(__dirname + '/ssl/development/server.key'),
  cert: fs.readFileSync(__dirname + '/ssl/development/server.crt'),
  ca: fs.readFileSync(__dirname + '/ssl/development/ca.crt'),
  requestCert: true,
  rejectUnauthorized: false
}

https.createServer(sslOptions, function (req, res) {
  counterHTTPS++;
  console.reset();
  console.log(chalk.bgGreen("\n\n\n\n---------------------------------------"+counterHTTPS+"---------------------------------------------\n\n"));
  console.log(chalk.bgGreen("PRE HEADER"));
  inspect(req.headers);
  console.log(chalk.bgGreen("SECURITY"));
  inspect(req.connection.encrypted);
  console.log(chalk.bgGreen("PRE URL"));
  inspect(req.url);
  console.log(chalk.bgGreen("PRE TARGET"));
  if(req.connection.encrypted == true)
    target = 'https:';
  else
    target = 'http:';
  target += '//' + req.headers.host;
  // target = 'https://' + req.headers.host;
  inspect(target);

  proxyHTTPS.proxyRequest(req, res, {
    target: target,
    enable : { xforward: true }
  });

}).listen(8000);

//////// EXAMPLE EXPRESS APP ///////////
http.createServer(function (req, res) {
  console.log(chalk.bgBlue("URL"));
  inspect(req.url);
  console.log(chalk.bgBlue("HEADER"));
  inspect(req.headers);
  console.log("received msg on new server", req.url + '\n' + JSON.stringify(req.headers, true, 2));
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.write({"data":'request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2)});
  res.end();
}).listen(9000);