diff --git a/server/auth/types/openid/helper.ts b/server/auth/types/openid/helper.ts index 2ba45f361..dfc948ba3 100644 --- a/server/auth/types/openid/helper.ts +++ b/server/auth/types/openid/helper.ts @@ -17,6 +17,7 @@ import wreck from '@hapi/wreck'; import { parse, stringify } from 'querystring'; import { CoreSetup } from 'opensearch-dashboards/server'; import { SecurityPluginConfigType } from '../../..'; +import { OpenSearchDashboardsRequest } from '../../../../../../src/core/server'; export function parseTokenResponse(payload: Buffer) { const payloadString = payload.toString(); @@ -30,19 +31,45 @@ export function parseTokenResponse(payload: Buffer) { return parse(payloadString); } -export function getBaseRedirectUrl(config: SecurityPluginConfigType, core: CoreSetup): string { +export function getRootUrl( + config: SecurityPluginConfigType, + core: CoreSetup, + request: OpenSearchDashboardsRequest +): string { + const host = core.http.getServerInfo().hostname; + const port = core.http.getServerInfo().port; + let protocol = core.http.getServerInfo().protocol; + let httpHost = `${host}:${port}`; + + if (config.openid?.trust_dynamic_headers) { + const xForwardedHost = (request.headers['x-forwarded-host'] as string) || undefined; + const xForwardedProto = (request.headers['x-forwarded-proto'] as string) || undefined; + if (xForwardedHost) { + httpHost = xForwardedHost; + } + if (xForwardedProto) { + protocol = xForwardedProto; + } + } + + return `${protocol}://${httpHost}`; +} + +export function getBaseRedirectUrl( + config: SecurityPluginConfigType, + core: CoreSetup, + request: OpenSearchDashboardsRequest +): string { if (config.openid?.base_redirect_url) { const baseRedirectUrl = config.openid.base_redirect_url; return baseRedirectUrl.endsWith('/') ? baseRedirectUrl.slice(0, -1) : baseRedirectUrl; } - const host = core.http.getServerInfo().hostname; - const port = core.http.getServerInfo().port; - const protocol = core.http.getServerInfo().protocol; + const rootUrl = getRootUrl(config, core, request); if (core.http.basePath.serverBasePath) { - return `${protocol}://${host}:${port}${core.http.basePath.serverBasePath}`; + return `${rootUrl}${core.http.basePath.serverBasePath}`; } - return `${protocol}://${host}:${port}`; + return rootUrl; } export async function callTokenEndpoint( diff --git a/server/auth/types/openid/routes.ts b/server/auth/types/openid/routes.ts index 078f52e6d..44e5220a6 100644 --- a/server/auth/types/openid/routes.ts +++ b/server/auth/types/openid/routes.ts @@ -89,7 +89,11 @@ export class OpenIdAuthRoutes { const query: any = { client_id: this.config.openid?.client_id, response_type: 'code', - redirect_uri: `${getBaseRedirectUrl(this.config, this.core)}/auth/openid/login`, + redirect_uri: `${getBaseRedirectUrl( + this.config, + this.core, + request + )}/auth/openid/login`, state: nonce, scope: this.openIdAuthConfig.scope, }; @@ -133,7 +137,7 @@ export class OpenIdAuthRoutes { const query: any = { grant_type: 'authorization_code', code: request.query.code, - redirect_uri: `${getBaseRedirectUrl(this.config, this.core)}/auth/openid/login`, + redirect_uri: `${getBaseRedirectUrl(this.config, this.core, request)}/auth/openid/login`, client_id: clientId, client_secret: clientSecret, }; @@ -192,7 +196,7 @@ export class OpenIdAuthRoutes { // authHeaderValue is the bearer header, e.g. "Bearer " const token = cookie?.credentials.authHeaderValue.split(' ')[1]; // get auth token const logoutQueryParams = { - post_logout_redirect_uri: getBaseRedirectUrl(this.config, this.core), + post_logout_redirect_uri: getBaseRedirectUrl(this.config, this.core, request), id_token_hint: token, }; diff --git a/server/index.ts b/server/index.ts index a25bca467..a682d070b 100644 --- a/server/index.ts +++ b/server/index.ts @@ -135,6 +135,7 @@ export const configSchema = schema.object({ root_ca: schema.string({ defaultValue: '' }), verify_hostnames: schema.boolean({ defaultValue: true }), refresh_tokens: schema.boolean({ defaultValue: true }), + trust_dynamic_headers: schema.boolean({ defaultValue: false }), }) ), proxycache: schema.maybe(