From 6c84e58c322b0e8dcb50a2bacbe3d68aba5b26e9 Mon Sep 17 00:00:00 2001 From: Zhongnan Su Date: Wed, 27 Oct 2021 15:27:04 -0700 Subject: [PATCH] Forward extra headers while using headless chromium (#194) --- server/routes/lib/createReport.ts | 38 +++---------------- server/routes/utils/constants.ts | 11 ++++-- .../utils/visual_report/visualReportHelper.ts | 16 +++----- 3 files changed, 19 insertions(+), 46 deletions(-) diff --git a/server/routes/lib/createReport.ts b/server/routes/lib/createReport.ts index 2c83e6b6..e5d550fc 100644 --- a/server/routes/lib/createReport.ts +++ b/server/routes/lib/createReport.ts @@ -28,7 +28,7 @@ import { REPORT_TYPE, REPORT_STATE, DELIVERY_TYPE, - SECURITY_CONSTANTS, + EXTRA_HEADERS, } from '../utils/constants'; import { @@ -46,6 +46,7 @@ import { updateReportState } from './updateReportState'; import { saveReport } from './saveReport'; import { SemaphoreInterface } from 'async-mutex'; import { AccessInfoType } from 'server'; +import _ from 'lodash'; export const createReport = async ( request: OpenSearchDashboardsRequest, @@ -75,9 +76,7 @@ export const createReport = async ( let reportId; const { - report_definition: { - report_params: reportParams, - }, + report_definition: { report_params: reportParams }, } = report; const { report_source: reportSource } = reportParams; @@ -103,40 +102,15 @@ export const createReport = async ( ? report.query_url : `${basePath}${report.query_url}`; const completeQueryUrl = `${protocol}://${hostname}:${port}${relativeUrl}`; - // Check if security is enabled. TODO: is there a better way to check? - let cookieObject: SetCookie | undefined; - if (request.headers.cookie) { - const cookies = request.headers.cookie.split(';'); - cookies.map((item: string) => { - const cookie = item.trim().split('='); - if (cookie[0] === SECURITY_CONSTANTS.AUTH_COOKIE_NAME) { - cookieObject = { - name: cookie[0], - value: cookie[1], - url: completeQueryUrl, - path: basePath, - }; - } - }); - } - // If header exists assuming that it needs forwarding - let additionalHeaders: Headers | undefined; - if (request.headers[SECURITY_CONSTANTS.PROXY_AUTH_USER_HEADER]) { - additionalHeaders = {} - additionalHeaders[SECURITY_CONSTANTS.PROXY_AUTH_USER_HEADER] = request.headers[SECURITY_CONSTANTS.PROXY_AUTH_USER_HEADER]; - additionalHeaders[SECURITY_CONSTANTS.PROXY_AUTH_IP_HEADER] = request.headers[SECURITY_CONSTANTS.PROXY_AUTH_IP_HEADER]; - if (request.headers[SECURITY_CONSTANTS.PROXY_AUTH_ROLES_HEADER]) { - additionalHeaders[SECURITY_CONSTANTS.PROXY_AUTH_ROLES_HEADER] = request.headers[SECURITY_CONSTANTS.PROXY_AUTH_ROLES_HEADER] - } - } + const extraHeaders = _.pick(request.headers, EXTRA_HEADERS); + const [value, release] = await semaphore.acquire(); try { createReportResult = await createVisualReport( reportParams, completeQueryUrl, logger, - cookieObject, - additionalHeaders, + extraHeaders, timezone ); } finally { diff --git a/server/routes/utils/constants.ts b/server/routes/utils/constants.ts index 8bb89058..e311c394 100644 --- a/server/routes/utils/constants.ts +++ b/server/routes/utils/constants.ts @@ -89,13 +89,16 @@ export const DEFAULT_MAX_SIZE = 10000; export const DEFAULT_REPORT_HEADER = '

OpenSearch Dashboards Reports

'; export const SECURITY_CONSTANTS = { - AUTH_COOKIE_NAME: 'security_authentication', TENANT_LOCAL_STORAGE_KEY: 'opendistro::security::tenant::show_popup', - PROXY_AUTH_USER_HEADER: 'x-proxy-user', - PROXY_AUTH_ROLES_HEADER: 'x-proxy-roles', - PROXY_AUTH_IP_HEADER: 'x-forwarded-for', }; +export const EXTRA_HEADERS = [ + 'cookie', + 'x-proxy-user', + 'x-proxy-roles', + 'x-forwarded-for', +]; + export const CHROMIUM_PATH = `${__dirname}/../../../.chromium/headless_shell`; /** diff --git a/server/routes/utils/visual_report/visualReportHelper.ts b/server/routes/utils/visual_report/visualReportHelper.ts index 94e6a166..0e079fdb 100644 --- a/server/routes/utils/visual_report/visualReportHelper.ts +++ b/server/routes/utils/visual_report/visualReportHelper.ts @@ -24,7 +24,7 @@ * permissions and limitations under the License. */ -import puppeteer, { SetCookie, Headers } from 'puppeteer-core'; +import puppeteer, { Headers } from 'puppeteer-core'; import createDOMPurify from 'dompurify'; import { JSDOM } from 'jsdom'; import { Logger } from '../../../../../../src/core/server'; @@ -40,13 +40,13 @@ import { getFileName } from '../helpers'; import { CreateReportResultType } from '../types'; import { ReportParamsSchemaType, VisualReportSchemaType } from 'server/model'; import fs from 'fs'; +import _ from 'lodash'; export const createVisualReport = async ( reportParams: ReportParamsSchemaType, queryUrl: string, logger: Logger, - cookie?: SetCookie, - additionalheaders?: Headers, + extraHeaders: Headers, timezone?: string ): Promise => { const { @@ -95,13 +95,9 @@ export const createVisualReport = async ( const page = await browser.newPage(); page.setDefaultNavigationTimeout(0); page.setDefaultTimeout(100000); // use 100s timeout instead of default 30s - if (cookie) { - logger.info('domain enables security, use session cookie to access'); - await page.setCookie(cookie); - } - if (additionalheaders) { - logger.info('domain passed proxy auth headers, passing to backend'); - await page.setExtraHTTPHeaders(additionalheaders); + // Set extra headers that are needed + if (!_.isEmpty(extraHeaders)) { + await page.setExtraHTTPHeaders(extraHeaders); } logger.info(`original queryUrl ${queryUrl}`); await page.goto(queryUrl, { waitUntil: 'networkidle0' });