mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Code] Apply socket authentication to non-code node (#29246)
This commit is contained in:
parent
5b1ab0f929
commit
64590617fd
3 changed files with 51 additions and 35 deletions
|
@ -10,6 +10,7 @@ import ClientIO from 'socket.io-client';
|
|||
|
||||
import { SocketKind } from '../../model';
|
||||
import { Logger } from '../log';
|
||||
import { getModifiedSocketRequest } from '../security';
|
||||
import { BASE_PLACEHOLDER, mainNodeBaseUrl } from './redirect';
|
||||
|
||||
export async function redirectSocketRoute(server: Server, redirect: string, log: Logger) {
|
||||
|
@ -60,8 +61,22 @@ export async function redirectSocketRoute(server: Server, redirect: string, log:
|
|||
});
|
||||
});
|
||||
|
||||
socketIO.on('connection', (socket: Socket) => {
|
||||
// add a POST ping route for `getRequest` to use
|
||||
server.securedRoute({
|
||||
method: 'POST',
|
||||
path: `/api/code/ping`,
|
||||
handler: () => 'pong',
|
||||
});
|
||||
|
||||
socketIO.on('connection', async (socket: Socket) => {
|
||||
log.debug(`User ${socket.id} connected, attaching handlers and register socket.`);
|
||||
|
||||
// 'request' is the modified hapi request object
|
||||
const request = await getModifiedSocketRequest(server, socket);
|
||||
if (!request) {
|
||||
socket.emit('connectionFailed', 'Socket connection failed');
|
||||
return socket.disconnect(true);
|
||||
}
|
||||
});
|
||||
socketIO.on('disconnect', () => {
|
||||
log.debug('User disconnected, removing handlers and unregister sockets.');
|
||||
|
|
|
@ -4,46 +4,18 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import Boom from 'boom';
|
||||
import { Server } from 'hapi';
|
||||
import { Handshake, Socket } from 'socket.io';
|
||||
import { Socket } from 'socket.io';
|
||||
|
||||
import { Logger } from '../log';
|
||||
import { getModifiedSocketRequest } from '../security';
|
||||
import { SocketService } from '../socket_service';
|
||||
|
||||
function getRequest(server: Server, { headers }: Handshake) {
|
||||
const url = `/api/code/ping`;
|
||||
|
||||
return server
|
||||
.inject({
|
||||
method: 'POST',
|
||||
url,
|
||||
headers,
|
||||
})
|
||||
.then(res => {
|
||||
if (res.statusCode !== 200) {
|
||||
throw Boom.unauthorized('Failed to authenticate socket connection');
|
||||
}
|
||||
return res.request;
|
||||
});
|
||||
}
|
||||
|
||||
async function getModifiedRequest(server: Server, socket: Socket) {
|
||||
try {
|
||||
return await getRequest(server, socket.handshake);
|
||||
} catch (err) {
|
||||
// on errors, notify the client and close the connection
|
||||
socket.emit('connectionFailed', { reason: err.message || 'Socket connection failed' });
|
||||
socket.disconnect(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function socketRoute(server: Server, socketService: SocketService, log: Logger) {
|
||||
const socketIO = socketService.io;
|
||||
|
||||
// add a POST ping route for `getRequest` to use
|
||||
server.route({
|
||||
server.securedRoute({
|
||||
method: 'POST',
|
||||
path: `/api/code/ping`,
|
||||
handler: () => 'pong',
|
||||
|
@ -52,10 +24,10 @@ export function socketRoute(server: Server, socketService: SocketService, log: L
|
|||
socketIO.on('connection', async (socket: Socket) => {
|
||||
log.info(`User ${socket.id} connected, attaching handlers and register socket.`);
|
||||
// 'request' is the modified hapi request object
|
||||
const request = await getModifiedRequest(server, socket);
|
||||
const request = await getModifiedSocketRequest(server, socket);
|
||||
if (!request) {
|
||||
log.error(`Request object not found. Disconnect the socket.`);
|
||||
return socket.disconnect();
|
||||
socket.emit('connectionFailed', 'Socket connection failed');
|
||||
return socket.disconnect(true);
|
||||
}
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import Boom from 'boom';
|
||||
import { Lifecycle, Request, ResponseToolkit, Server, ServerRoute } from 'hapi';
|
||||
import { Handshake, Socket } from 'socket.io';
|
||||
|
||||
export interface SecuredRoute extends ServerRoute {
|
||||
requireRoles?: string[];
|
||||
|
@ -80,3 +81,31 @@ export function enableSecurity(server: Server) {
|
|||
const secureRoute = new SecureRoute(server);
|
||||
secureRoute.install();
|
||||
}
|
||||
|
||||
function getSocketRequest(server: Server, { headers }: Handshake) {
|
||||
const url = `/api/code/ping`;
|
||||
|
||||
return server
|
||||
.inject({
|
||||
method: 'POST',
|
||||
url,
|
||||
headers,
|
||||
})
|
||||
.then(res => {
|
||||
if (res.statusCode !== 200) {
|
||||
throw Boom.unauthorized('Failed to authenticate socket connection');
|
||||
}
|
||||
return res.request;
|
||||
});
|
||||
}
|
||||
|
||||
export async function getModifiedSocketRequest(server: Server, socket: Socket) {
|
||||
try {
|
||||
return await getSocketRequest(server, socket.handshake);
|
||||
} catch (err) {
|
||||
// on errors, notify the client and close the connection
|
||||
socket.emit('connectionFailed', { reason: err.message || 'Socket connection failed' });
|
||||
socket.disconnect(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue