From 1f745610c6b38a41fe92bcf027fae367f2b983b0 Mon Sep 17 00:00:00 2001 From: Cecilia Avila <44245136+ceciliaavila@users.noreply.github.com> Date: Thu, 18 Jan 2024 21:31:13 +0000 Subject: [PATCH] fix: [#4544] JwtTokenExtractor.getIdentity:err! FetchError: request to https://login.botframework.com/v1/.well-known/openidconfiguration (#4583) * Provide proxy setting to openIdMetadata * Replace @azure/ms-rest-js with @azure/core-http * Add missing agent settings in getKeys call --- libraries/botframework-connector/package.json | 2 ++ .../src/auth/jwtTokenExtractor.ts | 15 +++++++++++---- .../src/auth/openIdMetadata.ts | 16 ++++++++++++---- .../parameterizedBotFrameworkAuthentication.ts | 9 ++++++--- yarn.lock | 15 +++++++++++++++ 5 files changed, 46 insertions(+), 11 deletions(-) diff --git a/libraries/botframework-connector/package.json b/libraries/botframework-connector/package.json index c24e94498d..0eed6e687a 100644 --- a/libraries/botframework-connector/package.json +++ b/libraries/botframework-connector/package.json @@ -34,7 +34,9 @@ "botbuilder-stdlib": "4.1.6", "botframework-schema": "4.1.6", "cross-fetch": "^3.0.5", + "https-proxy-agent": "^7.0.2", "jsonwebtoken": "^9.0.0", + "node-fetch": "^2.6.7", "rsa-pem-from-mod-exp": "^0.8.4", "zod": "^3.22.4", "openssl-wrapper": "^0.3.4" diff --git a/libraries/botframework-connector/src/auth/jwtTokenExtractor.ts b/libraries/botframework-connector/src/auth/jwtTokenExtractor.ts index fd2f1f71bf..7f713cf9af 100644 --- a/libraries/botframework-connector/src/auth/jwtTokenExtractor.ts +++ b/libraries/botframework-connector/src/auth/jwtTokenExtractor.ts @@ -12,6 +12,7 @@ import { EndorsementsValidator } from './endorsementsValidator'; import { OpenIdMetadata } from './openIdMetadata'; import { AuthenticationError } from './authenticationError'; import { StatusCodes } from 'botframework-schema'; +import { ProxySettings } from '@azure/core-http'; /** * A JWT token processing class that gets identity information and performs security token validation. @@ -32,17 +33,23 @@ export class JwtTokenExtractor { * @param tokenValidationParameters Token validation parameters. * @param metadataUrl Metadata Url. * @param allowedSigningAlgorithms Allowed signing algorithms. + * @param proxySettings The proxy settings for the request. */ - constructor(tokenValidationParameters: VerifyOptions, metadataUrl: string, allowedSigningAlgorithms: string[]) { + constructor( + tokenValidationParameters: VerifyOptions, + metadataUrl: string, + allowedSigningAlgorithms: string[], + proxySettings?: ProxySettings + ) { this.tokenValidationParameters = { ...tokenValidationParameters }; this.tokenValidationParameters.algorithms = allowedSigningAlgorithms; - this.openIdMetadata = JwtTokenExtractor.getOrAddOpenIdMetadata(metadataUrl); + this.openIdMetadata = JwtTokenExtractor.getOrAddOpenIdMetadata(metadataUrl, proxySettings); } - private static getOrAddOpenIdMetadata(metadataUrl: string): OpenIdMetadata { + private static getOrAddOpenIdMetadata(metadataUrl: string, proxySettings?: ProxySettings): OpenIdMetadata { let metadata = this.openIdMetadataCache.get(metadataUrl); if (!metadata) { - metadata = new OpenIdMetadata(metadataUrl); + metadata = new OpenIdMetadata(metadataUrl, proxySettings); this.openIdMetadataCache.set(metadataUrl, metadata); } diff --git a/libraries/botframework-connector/src/auth/openIdMetadata.ts b/libraries/botframework-connector/src/auth/openIdMetadata.ts index c084d30037..49d5ae9f01 100644 --- a/libraries/botframework-connector/src/auth/openIdMetadata.ts +++ b/libraries/botframework-connector/src/auth/openIdMetadata.ts @@ -8,9 +8,11 @@ import * as getPem from 'rsa-pem-from-mod-exp'; import base64url from 'base64url'; -import fetch from 'cross-fetch'; +import fetch from 'node-fetch'; +import { HttpsProxyAgent } from 'https-proxy-agent'; import { AuthenticationError } from './authenticationError'; import { StatusCodes } from 'botframework-schema'; +import { ProxySettings } from '@azure/core-http'; /** * Class in charge of manage OpenId metadata. @@ -23,8 +25,9 @@ export class OpenIdMetadata { * Initializes a new instance of the [OpenIdMetadata](xref:botframework-connector.OpenIdMetadata) class. * * @param url Metadata Url. + * @param proxySettings The proxy settings for the request. */ - constructor(private url: string) {} + constructor(private url: string, private proxySettings?: ProxySettings) {} /** * Gets the Signing key. @@ -56,12 +59,17 @@ export class OpenIdMetadata { * @private */ private async refreshCache(): Promise { - const res = await fetch(this.url); + let agent = null; + if (this.proxySettings) { + const proxyUrl = `http://${this.proxySettings.host}:${this.proxySettings.port}`; + agent = new HttpsProxyAgent(proxyUrl); + } + const res = await fetch(this.url, { agent: agent }); if (res.ok) { const openIdConfig = (await res.json()) as IOpenIdConfig; - const getKeyResponse = await fetch(openIdConfig.jwks_uri); + const getKeyResponse = await fetch(openIdConfig.jwks_uri, { agent: agent }); if (getKeyResponse.ok) { this.lastUpdated = new Date().getTime(); this.keys = (await getKeyResponse.json()).keys as IKey[]; diff --git a/libraries/botframework-connector/src/auth/parameterizedBotFrameworkAuthentication.ts b/libraries/botframework-connector/src/auth/parameterizedBotFrameworkAuthentication.ts index 21d14f02ce..41398dd369 100644 --- a/libraries/botframework-connector/src/auth/parameterizedBotFrameworkAuthentication.ts +++ b/libraries/botframework-connector/src/auth/parameterizedBotFrameworkAuthentication.ts @@ -303,7 +303,8 @@ export class ParameterizedBotFrameworkAuthentication extends BotFrameworkAuthent const tokenExtractor = new JwtTokenExtractor( verifyOptions, this.toBotFromEmulatorOpenIdMetadataUrl, - AuthenticationConstants.AllowedSigningAlgorithms + AuthenticationConstants.AllowedSigningAlgorithms, + this.connectorClientOptions?.proxySettings ); const parts: string[] = authHeader.split(' '); @@ -389,7 +390,8 @@ export class ParameterizedBotFrameworkAuthentication extends BotFrameworkAuthent const tokenExtractor: JwtTokenExtractor = new JwtTokenExtractor( verifyOptions, this.toBotFromEmulatorOpenIdMetadataUrl, - AuthenticationConstants.AllowedSigningAlgorithms + AuthenticationConstants.AllowedSigningAlgorithms, + this.connectorClientOptions?.proxySettings ); const identity: ClaimsIdentity = await tokenExtractor.getIdentityFromAuthHeader( @@ -475,7 +477,8 @@ export class ParameterizedBotFrameworkAuthentication extends BotFrameworkAuthent const tokenExtractor: JwtTokenExtractor = new JwtTokenExtractor( tokenValidationParameters, this.toBotFromChannelOpenIdMetadataUrl, - AuthenticationConstants.AllowedSigningAlgorithms + AuthenticationConstants.AllowedSigningAlgorithms, + this.connectorClientOptions?.proxySettings ); const identity: ClaimsIdentity = await tokenExtractor.getIdentityFromAuthHeader( diff --git a/yarn.lock b/yarn.lock index aa9c70a19e..e92a4f8ce5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2838,6 +2838,13 @@ agent-base@6: dependencies: debug "4" +agent-base@^7.0.2: + version "7.1.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" + integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== + dependencies: + debug "^4.3.4" + agentkeepalive@^4.1.3: version "4.1.4" resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.1.4.tgz#d928028a4862cb11718e55227872e842a44c945b" @@ -7528,6 +7535,14 @@ https-proxy-agent@5.0.0, https-proxy-agent@^5.0.0: agent-base "6" debug "4" +https-proxy-agent@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz#e2645b846b90e96c6e6f347fb5b2e41f1590b09b" + integrity sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA== + dependencies: + agent-base "^7.0.2" + debug "4" + humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed"