Skip to content

Commit 227fe8a

Browse files
committed
Fixes proxy issue with browser auth
1 parent c61b953 commit 227fe8a

File tree

3 files changed

+104
-1
lines changed

3 files changed

+104
-1
lines changed

desktop/src/client/core/aad/auth-provider.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import MSALCachePlugin from "./msal-cache-plugin";
1313
import { AuthObserver } from "./auth-observer";
1414
import { shell } from "electron";
1515
import { AuthLoopbackClient } from "./auth-loopback-client";
16+
import { ProxyNetworkClient } from "./proxy-network-client";
17+
18+
import "global-agent/bootstrap";
1619

1720
const MSAL_SCOPES = ["user_impersonation"];
1821

@@ -245,18 +248,21 @@ export default class AuthProvider {
245248
private async _createClient(tenantId: string):
246249
Promise<PublicClientApplication> {
247250
const proxyUrl = await this._loadProxyUrl();
251+
let networkClient;
248252

249253
if (proxyUrl) {
250254
log.info(`[${tenantId}] Proxying auth endpoints through ` +
251255
proxyUrl);
256+
process.env.GLOBAL_AGENT_HTTP_PROXY = proxyUrl;
257+
networkClient = new ProxyNetworkClient(proxyUrl);
252258
}
253259

254260
const authority =
255261
`${this.app.properties.azureEnvironment.aadUrl}${tenantId}/`;
256262

257263
return new PublicClientApplication({
258264
system: {
259-
proxyUrl
265+
networkClient
260266
},
261267
auth: {
262268
clientId: this.config.clientId,
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import type { INetworkModule, NetworkRequestOptions, NetworkResponse } from "@azure/msal-node";
2+
import * as HttpsProxyAgent from "https-proxy-agent";
3+
import fetch from "node-fetch";
4+
5+
/**
6+
* Placeholder for msal-node's network module which uses node-fetch to support
7+
* HTTP proxy configurations with authorization
8+
*
9+
* @see https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/6527#issuecomment-2077953882
10+
*/
11+
export class ProxyNetworkClient implements INetworkModule {
12+
private proxyAgent: HttpsProxyAgent;
13+
constructor(proxyUrl: string) {
14+
this.proxyAgent = new HttpsProxyAgent(proxyUrl);
15+
}
16+
17+
sendGetRequestAsync<T>(url: string, options?: NetworkRequestOptions): Promise<NetworkResponse<T>> {
18+
return this.sendRequestAsync(url, "GET", options);
19+
}
20+
sendPostRequestAsync<T>(url: string, options?: NetworkRequestOptions): Promise<NetworkResponse<T>> {
21+
return this.sendRequestAsync(url, "POST", options);
22+
}
23+
24+
private async sendRequestAsync<T>(
25+
url: string,
26+
method: "GET" | "POST",
27+
options: NetworkRequestOptions = {},
28+
): Promise<NetworkResponse<T>> {
29+
try {
30+
const requestOptions = {
31+
method: method,
32+
headers: options.headers,
33+
body: method === "POST" ? options.body : undefined,
34+
agent: this.proxyAgent,
35+
};
36+
37+
const response = await fetch(url, requestOptions);
38+
const data = await response.json() as any;
39+
40+
const headersObj: Record<string, string> = {};
41+
response.headers.forEach((value, key) => {
42+
headersObj[key] = value;
43+
});
44+
45+
return {
46+
headers: headersObj,
47+
body: data,
48+
status: response.status,
49+
};
50+
} catch (err) {
51+
console.error("Proxy request error", err);
52+
throw err;
53+
}
54+
}
55+
}

desktop/src/client/core/batch-explorer-application.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export class BatchExplorerApplication {
8686
this._setupProcessEvents();
8787
this._registerFileProtocol();
8888
await this.proxySettings.init();
89+
this._applyProxySettings();
8990
this.storageBlobAdapter.init();
9091
}
9192

@@ -365,4 +366,45 @@ export class BatchExplorerApplication {
365366
callback({ cancel: false, requestHeaders: details.requestHeaders });
366367
});
367368
}
369+
370+
private async _trustedDomains(): Promise<string[]> {
371+
return [
372+
"https://raw.githubusercontent.com",
373+
"https://batch.azure.com", // Public data-plane API calls
374+
this.properties.azureEnvironment.aadUrl,
375+
this.properties.azureEnvironment.arm,
376+
this.properties.azureEnvironment.batch,
377+
this.properties.azureEnvironment.msGraph,
378+
this.properties.azureEnvironment.storageEndpoint
379+
].map(url => {
380+
try {
381+
// Ensure the URL has a protocol (default to "https://")
382+
const normalized = url.startsWith("http") ? url : `https://${url}`;
383+
return new URL(normalized).hostname;
384+
} catch (error) {
385+
console.error(`Invalid URL: ${url}`, error);
386+
return null; // Handle invalid URLs gracefully
387+
}
388+
}).filter(Boolean);
389+
}
390+
391+
private async _applyProxySettings() {
392+
const settings = await this.proxySettings.settings;
393+
394+
const conf = settings.http || settings.https;
395+
const proxyUrl = `${conf.protocol}://${conf.host}:${conf.port}`;
396+
397+
session.defaultSession.setProxy({ proxyRules: proxyUrl });
398+
process.env.HTTP_PROXY = proxyUrl;
399+
400+
const trustedDomains = await this._trustedDomains();
401+
session.defaultSession.setCertificateVerifyProc((request, verifyCert) => {
402+
if (trustedDomains.some(host => request.hostname.includes(host))) {
403+
verifyCert(0); // trust the certificate
404+
} else {
405+
console.error("Untrusted certificate", request.hostname);
406+
verifyCert(-3);
407+
}
408+
});
409+
}
368410
}

0 commit comments

Comments
 (0)