Skip to content

Commit

Permalink
Add Proxy Auth to Multi Auth Options (#2076)
Browse files Browse the repository at this point in the history
* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

* Add Proxy Auth to Multi Auth Options

Signed-off-by: Stephen Crawford <[email protected]>

---------

Signed-off-by: Stephen Crawford <[email protected]>
(cherry picked from commit c45b931)
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
github-actions[bot] committed Aug 20, 2024
1 parent e78ba0d commit a6203b2
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 3 deletions.
8 changes: 7 additions & 1 deletion public/apps/login/login-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,10 @@ export function LoginPage(props: LoginPageDeps) {
);
}

if (authOpts.length > 1) {
if (
authOpts.length > 1 &&
!(authOpts.includes(AuthType.PROXY) && authOpts.length === 2)
) {
formBody.push(<EuiSpacer size="xs" />);
formBody.push(<EuiHorizontalRule size="full" margin="xl" />);
formBody.push(<EuiSpacer size="xs" />);
Expand All @@ -258,6 +261,9 @@ export function LoginPage(props: LoginPageDeps) {
formBodyOp.push(renderLoginButton(AuthType.SAML, samlAuthLoginUrl, samlConfig));
break;
}
case AuthType.PROXY: {
break;

Check warning on line 265 in public/apps/login/login-page.tsx

View check run for this annotation

Codecov / codecov/patch

public/apps/login/login-page.tsx#L265

Added line #L265 was not covered by tests
}
default: {
setloginFailed(true);
setloginError(
Expand Down
22 changes: 20 additions & 2 deletions server/auth/types/multiple/multi_auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ import { AuthType, LOGIN_PAGE_URI } from '../../../../common';
import { composeNextUrlQueryParam } from '../../../utils/next_url';
import { MultiAuthRoutes } from './routes';
import { SecuritySessionCookie } from '../../../session/security_cookie';
import { BasicAuthentication, OpenIdAuthentication, SamlAuthentication } from '../../types';
import {
BasicAuthentication,
OpenIdAuthentication,
ProxyAuthentication,
SamlAuthentication,
} from '../../types';

export class MultipleAuthentication extends AuthenticationType {
private authTypes: string | string[];
Expand Down Expand Up @@ -93,6 +98,19 @@ export class MultipleAuthentication extends AuthenticationType {
this.authHandlers.set(AuthType.SAML, SamlAuth);
break;
}
case AuthType.PROXY: {
const ProxyAuth = new ProxyAuthentication(
this.config,
this.sessionStorageFactory,
this.router,
this.esClient,
this.coreSetup,
this.logger
);
await ProxyAuth.init();
this.authHandlers.set(AuthType.PROXY, ProxyAuth);
break;
}
default: {
throw new Error(`Unsupported authentication type: ${this.authTypes[i]}`);
}
Expand All @@ -115,7 +133,7 @@ export class MultipleAuthentication extends AuthenticationType {
async getAdditionalAuthHeader(
request: OpenSearchDashboardsRequest<unknown, unknown, unknown, any>
): Promise<any> {
// To Do: refactor this method to improve the effiency to get cookie, get cookie from input parameter
// To Do: refactor this method to improve the efficiency to get cookie, get cookie from input parameter
const cookie = await this.sessionStorageFactory.asScoped(request).get();
const reqAuthType = cookie?.authType?.toLowerCase();

Expand Down
4 changes: 4 additions & 0 deletions test/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ export const ADMIN_PASSWORD: string = process.env.ADMIN_PASSWORD || 'admin';
const ADMIN_USER_PASS: string = `${ADMIN_USER}:${ADMIN_PASSWORD}`;
export const ADMIN_CREDENTIALS: string = `Basic ${Buffer.from(ADMIN_USER_PASS).toString('base64')}`;
export const AUTHORIZATION_HEADER_NAME: string = 'Authorization';

export const PROXY_USER: string = 'x-proxy-user';
export const PROXY_ROLE: string = 'x-proxy-roles';
export const PROXY_ADMIN_ROLE: string = 'admin';
209 changes: 209 additions & 0 deletions test/jest_integration/proxy_multiauth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/*
* Copyright OpenSearch Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import * as osdTestServer from '../../../../src/core/test_helpers/osd_server';
import { Root } from '../../../../src/core/server/root';
import { resolve } from 'path';
import { describe, it, beforeAll, afterAll } from '@jest/globals';
import {
ADMIN_CREDENTIALS,
OPENSEARCH_DASHBOARDS_SERVER_USER,
OPENSEARCH_DASHBOARDS_SERVER_PASSWORD,
ADMIN_USER,
PROXY_ADMIN_ROLE,
} from '../constant';
import wreck from '@hapi/wreck';

describe('start OpenSearch Dashboards server', () => {
let root: Root;
let config;

beforeAll(async () => {
root = osdTestServer.createRootWithSettings(
{
plugins: {
scanDirs: [resolve(__dirname, '../..')],
},
home: { disableWelcomeScreen: true },
server: {
host: 'localhost',
port: 5601,
},
logging: {
silent: true,
verbose: false,
},
opensearch: {
hosts: ['https://localhost:9200'],
ignoreVersionMismatch: true,
ssl: { verificationMode: 'none' },
username: OPENSEARCH_DASHBOARDS_SERVER_USER,
password: OPENSEARCH_DASHBOARDS_SERVER_PASSWORD,
requestHeadersAllowlist: [
'securitytenant',
'Authorization',
'x-forwarded-for',
'x-proxy-user',
'x-proxy-roles',
],
},
opensearch_security: {
auth: {
anonymous_auth_enabled: false,
type: ['basicauth', 'proxy'],
multiple_auth_enabled: true,
},
proxycache: {
user_header: 'x-proxy-user',
roles_header: 'x-proxy-roles',
},
multitenancy: {
enabled: true,
tenants: {
enable_global: true,
enable_private: true,
preferred: ['Private', 'Global'],
},
},
},
},
{
// to make ignoreVersionMismatch setting work
// can be removed when we have corresponding ES version
dev: true,
}
);

console.log('Starting OpenSearchDashboards server..');
await root.setup();
await root.start();

console.log('Starting to Download Flights Sample Data');
await wreck.post('http://localhost:5601/api/sample_data/flights', {
payload: {},
rejectUnauthorized: false,
headers: {
'Content-Type': 'application/json',
authorization: ADMIN_CREDENTIALS,
security_tenant: 'global',
},
});
console.log('Downloaded Sample Data');
const getConfigResponse = await wreck.get(
'https://localhost:9200/_plugins/_security/api/securityconfig',
{
rejectUnauthorized: false,
headers: {
authorization: ADMIN_CREDENTIALS,
},
}
);
const responseBody = (getConfigResponse.payload as Buffer).toString();
config = JSON.parse(responseBody).config;
const proxyConfig = {
http_enabled: true,
transport_enabled: true,
order: 0,
http_authenticator: {
challenge: false,
type: 'proxy',
config: {
user_header: 'x-proxy-user',
roles_header: 'x-proxy-roles',
},
},
authentication_backend: {
type: 'noop',
config: {},
},
};
try {
config.dynamic!.authc!.proxy_auth_domain = proxyConfig;
config.dynamic!.authc!.basic_internal_auth_domain.http_authenticator.challenge = false;
config.dynamic!.http!.anonymous_auth_enabled = false;
await wreck.put('https://localhost:9200/_plugins/_security/api/securityconfig/config', {
payload: config,
rejectUnauthorized: false,
headers: {
'Content-Type': 'application/json',
authorization: ADMIN_CREDENTIALS,
},
});
} catch (error) {
console.log('Got an error while updating security config!!', error.stack);
fail(error);
}
});

afterAll(async () => {
console.log('Remove the Sample Data');
await wreck
.delete('http://localhost:5601/api/sample_data/flights', {
rejectUnauthorized: false,
headers: {
'Content-Type': 'application/json',
authorization: ADMIN_CREDENTIALS,
},
})
.then((value) => {
Promise.resolve(value);
})
.catch((value) => {
Promise.resolve(value);
});
console.log('Remove the Security Config');
await wreck
.patch('https://localhost:9200/_plugins/_security/api/securityconfig', {
payload: [
{
op: 'remove',
path: '/config/dynamic/authc/proxy_auth_domain',
},
],
rejectUnauthorized: false,
headers: {
'Content-Type': 'application/json',
authorization: ADMIN_CREDENTIALS,
},
})
.then((value) => {
Promise.resolve(value);
})
.catch((value) => {
Promise.resolve(value);
});
// shutdown OpenSearchDashboards server
await root.shutdown();
});

it('Verify Proxy access to dashboards', async () => {
console.log('Wreck access home page');
await wreck
.get('http://localhost:5601/app/home#', {
rejectUnauthorized: true,
headers: {
'Content-Type': 'application/json',
PROXY_USER: ADMIN_USER,
PROXY_ROLE: PROXY_ADMIN_ROLE,
},
})
.then((value) => {
Promise.resolve(value);
})
.catch((value) => {
Promise.resolve(value);
});
});
});

0 comments on commit a6203b2

Please sign in to comment.