[Code] Apply socket authentication to non-code node (#29246)

This commit is contained in:
Mengwei Ding 2019-01-25 06:54:04 +08:00 committed by Fuyao Zhao
parent 5b1ab0f929
commit 64590617fd
3 changed files with 51 additions and 35 deletions

View file

@ -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.');

View file

@ -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', () => {

View file

@ -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;
}
}