feat: use websocket header to pass the auth token
Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This commit is contained in:
@@ -19,7 +19,11 @@ import {
|
||||
EventSubscriber,
|
||||
} from '@backstage/plugin-events-node';
|
||||
import { Logger } from 'winston';
|
||||
import { ServiceOptions, SignalConnection } from './types';
|
||||
import {
|
||||
ServiceOptions,
|
||||
SignalConnection,
|
||||
SignalsEventBrokerPayload,
|
||||
} from './types';
|
||||
import { RawData, WebSocket, WebSocketServer } from 'ws';
|
||||
import { IncomingMessage } from 'http';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
@@ -31,13 +35,6 @@ import {
|
||||
IdentityApiGetIdentityRequest,
|
||||
} from '@backstage/plugin-auth-node';
|
||||
|
||||
/** @public */
|
||||
export type SignalsEventBrokerPayload = {
|
||||
recipients?: string[];
|
||||
topic?: string;
|
||||
message?: JsonObject;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export class SignalsService implements EventSubscriber {
|
||||
private readonly serverId: string;
|
||||
@@ -83,9 +80,18 @@ export class SignalsService implements EventSubscriber {
|
||||
* @param req - Request
|
||||
*/
|
||||
handleUpgrade = async (req: Request) => {
|
||||
const identity = await this.identity.getIdentity({
|
||||
request: req,
|
||||
});
|
||||
let identity: BackstageIdentityResponse | undefined = undefined;
|
||||
|
||||
// Authentication token is passed in Sec-WebSocket-Protocol header as there
|
||||
// is no other way to pass the token with plain websockets
|
||||
const token = req.headers['sec-websocket-protocol'];
|
||||
if (token) {
|
||||
identity = await this.identity.getIdentity({
|
||||
request: {
|
||||
headers: { authorization: token },
|
||||
},
|
||||
} as IdentityApiGetIdentityRequest);
|
||||
}
|
||||
|
||||
this.server.handleUpgrade(
|
||||
req,
|
||||
@@ -161,23 +167,6 @@ export class SignalsService implements EventSubscriber {
|
||||
);
|
||||
connection.subscriptions.delete(message.topic as string);
|
||||
}
|
||||
|
||||
if (message.action === 'authenticate' && message.token) {
|
||||
this.logger.info(`Connection ${connection.id} authenticated`);
|
||||
this.identity
|
||||
.getIdentity({
|
||||
request: {
|
||||
headers: { authorization: message.token },
|
||||
},
|
||||
} as IdentityApiGetIdentityRequest)
|
||||
.then(identity => {
|
||||
if (identity) {
|
||||
connection.user = identity.identity.userEntityRef;
|
||||
connection.ownershipEntityRefs =
|
||||
identity.identity.ownershipEntityRefs;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@ import { IdentityApi } from '@backstage/plugin-auth-node';
|
||||
import { EventBroker } from '@backstage/plugin-events-node';
|
||||
import { Logger } from 'winston';
|
||||
import { WebSocket } from 'ws';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
|
||||
/**
|
||||
* @public
|
||||
@@ -27,6 +28,13 @@ export type ServiceOptions = {
|
||||
identity: IdentityApi;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export type SignalsEventBrokerPayload = {
|
||||
recipients?: string[];
|
||||
topic?: string;
|
||||
message?: JsonObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user