Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExpressOIDC requests not going through configured proxy #15

Open
2 of 9 tasks
alihaghani opened this issue Mar 3, 2020 · 22 comments
Open
2 of 9 tasks

ExpressOIDC requests not going through configured proxy #15

alihaghani opened this issue Mar 3, 2020 · 22 comments

Comments

@alihaghani
Copy link

I'm submitting this issue for the package(s):

I'm submitting a:

  • Bug report
  • Feature request
  • Other (Describe below)

Current behavior

Per the documentation here, I have installed openid-client@2.5.0 (the latest version does not allow for accessing the issuer as outlined in the docs) and added the following lines of code:

...
process.env.http_proxy = '[protocol]://[user]:[pass]@[proxyUrl]:[port]';
process.env.https_proxy = '[protocol]://[user]:[pass]@[proxyUrl]:[port]';

const Issuer = require('openid-client').Issuer;

Issuer.useRequest();
const { ExpressOIDC } = require('@okta/oidc-middleware');
const oidc = new ExpressOIDC({ ... })
...

However, the requests for Okta authentication do not go through the provided proxy.

The only way I've been able to get the requests to actually go through the provided proxy is by adding

Issuer.useRequest();

after line 15 in node_modules/@okta/oidc-middleware/src/oidcUtil.js.

Expected behavior

Requests should go through the proxy if the documented configuration is done without requiring to modify the module files directly.

Environment

  • Package Version: 3.0.0
  • Browser: Chrome 79.0.3945.130
  • OS: macOS 10.15.2
  • Node version (node -v): v10.15.3
@aarongranick-okta
Copy link
Contributor

@alihaghani Thank you for bringing this to our attention. What version of oidc-middleware are you using? Our current version is using openid-client@3.12. According to the changelog the useRequest() method was dropped in version 3.

We will investigate how to fix the proxy behavior for the current version.

Internal ref: OKTA-282367

@alihaghani
Copy link
Author

I'm currently using version 3.0.0 of @okta/oidc-middleware. Is there an older version I can use where the proxy configuration works as documented?

@aarongranick-okta
Copy link
Contributor

@alihaghani
Copy link
Author

To clarify the docs, I need to install openid-client@2.5.0 separately in order to require it in my app. Correct?

npm i openid-client@2.5.0

Add the following before instantiating ExpressOIDC:

const Issuer = require('openid-client').Issuer;
Issuer.useRequest();

@aarongranick-okta
Copy link
Contributor

@alihaghani I believe in order to get it to work you need to access the actual instance of openid-client that is being used by oidc-middleware, since it is modifying the internal state of that running module instance. So that probably means adding the openid-client dependency in your own package.json, but also using some mechanism to avoid duplicate copies of the module being installed. If you reference both oidc-middleware and openid-client in your package.json and they are using the same version, wiping your node_modules folder and installing with yarn should avoid any duplications. I think you will want to see that node_modules/oidc-middleware/node_modules does not contain openid-client, but it is using the copy in the higher directory node_modules. If you are not using yarn, you can have a script to manually rm -rf node_modules/oidc-middleware/node_modules/openid-client to force it to use the copy in your project directory.

@alihaghani
Copy link
Author

At a state now with @okta/oidc-middleware@2.1.0 where openid-client@2.5.0 is in my project package.json and shows up under the project node_modules and not node_modules/@okta/oidc-middleware/node_modules.

Order of lines of code:

process.env.http_proxy = '[protocol]://[user]:[pass]@[proxyUrl]:[port]';
process.env.https_proxy = '[protocol]://[user]:[pass]@[proxyUrl]:[port]';

const { ExpressOIDC } = require('@okta/oidc-middleware');
const { Issuer } = require('openid-client');
...
Issuer.useRequest();
...
oidc = new ExpressOIDC(oidcConfig);

However, the requests still don't seem to be going through the proxy.

@swiftone
Copy link

swiftone commented Mar 6, 2020

@alihaghani - You may have better results by reaching out to our support team ( developers@okta.com ) who can dig into your use-case and offer suggestions.

We are interested in getting proxies working with this package, and the openid-client Request option from our documentation is no longer an option.

Please let us know if you find a solution before we do.

@alihaghani
Copy link
Author

@swiftone Are you able to provide a timeline for when proxies will be supported again?

Current solution seems to be maintaing a fork of @okta/oidc-middleware@2.5.0 with the Issuer.useRequest() line added in the oidcUtil.js file as mentioned above which is not ideal.

@swiftone
Copy link

@alihaghani - No timeline. Currently you're the only user I recall having this request, though I am only aware of requests via GH so the business may know of others.

Have you reached out to the support team?

@joshuakwaite
Copy link

I would also love for this to be supported again, or at least the documentation updated so that it doesn't appear to be supported when it is not.

@shuowu
Copy link
Contributor

shuowu commented Aug 11, 2020

@joshuakwaite We are investigating on the issue, will update in this thread when a solution found.

@trickreich
Copy link

Would also be interested in a solution.

@aarongranick-okta
Copy link
Contributor

aarongranick-okta commented Oct 2, 2020

@trickreich We are aware of flaws in the openid-client module used by our Express SDK and are currently investigating a new solution. Unfortunately, at this time I don't have any precise estimates on when that new solution will be available, but it is at least a few months away.

Okta does implement OpenId Connect / OAuth 2.0 according to the spec, so it should be possible to build a solution using any off-the-shelf component which adheres to the standard.

https://developer.okta.com/docs/reference/api/oidc/

If you do find a working solution, we would be very interested in hearing about it!

@trickreich
Copy link

trickreich commented Oct 5, 2020

Found following solution:

const { custom } = require('openid-client');
const tunnel = require('tunnel');

custom.setHttpOptionsDefaults({
	agent: {
		https: tunnel.httpsOverHttp({
			proxy: {
				host: 'yourproxyhostname',
				port: 8081,
			}
		})
	}
});

I've tested Okta for our company last week.
Sadly the documentation isn't up to date here: https://developer.okta.com/docs/guides/sign-into-web-app/nodeexpress/configure-packages/
Needed properties have changed.

@jespersoderlund
Copy link

I tried the solution from @trickreich but I could not get it to work, it doesn't seem to pickup the default HTTP options that are being set so the callouts from the OIDC middleware are not going through the proxy.

I added the debug-hooks as suggested in https://github.com/panva/node-openid-client/blob/master/docs/README.md#customizing-http-requests but they do not get triggered, so I suspect that the httpOptions are not picked-up at all.

I'm setting the custom options before the ExpressOIDC is created.

Any tips on how to troubleshoot this further?

@jespersoderlund
Copy link

I'll add my findings after some troubleshooting where I got this working. It was a case of the code showed by @trickreich does work, but I added the 'openid-client' module as a dependency to the application, but what was being used by the ExpressOIDC middleware was it's own nested dependency. Eliminating that problem fixed the issue.

@shuowu
Copy link
Contributor

shuowu commented Oct 15, 2020

@jespersoderlund There are some examples from openid-client doc that may help. https://github.com/panva/node-openid-client/blob/master/docs/README.md#customizing-individual-http-requests

Meanwhile, we are also investigating a stable solution for the issue.

@geekf
Copy link

geekf commented Feb 10, 2021

@shuowu: I have recently faced this issue too while upgrading to latest version of OIDC middleware. Turns out we were still using version 1.0.0 to avoid dealing with this. I am quite sure there would be other enterprises too doing the same as servers are rarely allowed direct connection to an external domain.

@denysoblohin-okta denysoblohin-okta transferred this issue from okta/okta-oidc-js Oct 29, 2021
@lvinet
Copy link

lvinet commented Dec 6, 2021

I did not find any satisfactory solution using @okta /oidc-middleware@4.3.0 with a proxy in okta forum or github issues to solve this issue.
I decided to modify some node modules associated to this Okta module. I hope it will help to find a better solution.

In @okta/oidc-middleware/src/oidcUtil.js add:

const tunnel = require('tunnel');
var tunnelingAgent = {}
if ((process.env.PROXY_URL) && (process.env.PROXY_PORT))
{
tunnelingAgent = tunnel.httpsOverHttp({
proxy: {
host: process.env.PROXY_URL,
port: process.env.PROXY_PORT
}
});
}

Issuer[custom.http_options] = function(options) {
options = customizeUserAgent(options);
options.agent = tunnelingAgent
options.timeout = timeout || 10000;
return options;
};

In @okta/oidc-middleware/src/logout.js add:

const tunnel = require('tunnel');
var tunnelingAgent = {}
if ((process.env.PROXY_URL) && (process.env.PROXY_PORT))
{
tunnelingAgent = tunnel.httpsOverHttp({
proxy: {
host: process.env.PROXY_URL,
port: process.env.PROXY_PORT
}
});
}

const makeAuthorizationHeader = ({ client_id, client_secret }) =>
'Basic ' + Buffer.from(${client_id}:${client_secret}).toString('base64');

const makeTokenRevoker = ({ issuer, client_id, client_secret, errorHandler }) => {
const revokeEndpoint = ${issuer}/v1/revoke;
return ({ token_hint, token }) => {
return fetch(revokeEndpoint, {
method: 'POST',
agent : tunnelingAgent,
headers: {
'accepts': 'application/json',
'content-type': 'application/x-www-form-urlencoded',
'authorization': makeAuthorizationHeader({ client_id, client_secret }),
},
body: querystring.stringify({token, token_type_hint: token_hint}),
})
// eslint-disable-next-line promise/no-nesting
.then( r => r.ok ? r : r.text().then(message => Promise.reject(new OIDCMiddlewareError('revokeError', message)) ))
.catch( errorHandler ) // catch and emit - this promise chain can never fail
};
}

In openid-client/lib/src/helpers/request.js add:

const tunnel = require('tunnel');
var tunnelingAgent = {}
if ((process.env.PROXY_URL) && (process.env.PROXY_PORT))
{
tunnelingAgent = tunnel.httpsOverHttp({
proxy: {
host: process.env.PROXY_URL,
port: process.env.PROXY_PORT
}
});
}

module.exports = function request(options, { mTLS = false } = {}) {
const { url } = options;
isAbsoluteUrl(url);
const optsFn = this[HTTP_OPTIONS];
let opts;
if (optsFn) {
opts = optsFn.call(this, defaultsDeep(options, DEFAULT_HTTP_OPTIONS));
} else {
opts = options;
}
opts.agent = tunnelingAgent

if (mTLS && (!opts.key || !opts.cert)) {
throw new TypeError('mutual-TLS certificate and key not set');
}
return got(opts);
};

@FiretronP75
Copy link

I need to use a proxy too. I work for a big company. We will reach out to the support team...

@FiretronP75
Copy link

Proxy support was just added to https://github.com/okta/okta-jwt-verifier-js today. Maybe this package can do it the same way.

@Tiuipuv
Copy link

Tiuipuv commented Sep 18, 2024

@aarongranick-okta Any updates on this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests