Authorizer custom is not being triggered for websocket connection event

I'm currently working on implementing a custom authorizer for an API Gateway Websocket API.

Below is my custom authorizer implementation using CDK:

const authFunc = new lambda.Function(scope, utils.prefixed("WebsocketAuth"), {
    runtime: lambda.Runtime.NODEJS_18_X,
    handler: `auth.handler`,
    code: lambda.Code.fromAsset(lambdaPath),
    environment: {
        API_KEY_ID: apiKey.keyId
    }
});

const authorizer = new WebSocketLambdaAuthorizer(
    "WebsocketAuth",
    authFunc
);

const webSocketApi = new apigatewayv2.WebSocketApi(scope, 'WebSocketApi', {
    connectRouteOptions: {
        authorizer,
        integration: new integrations.WebSocketLambdaIntegration('ConnectHandler', connectFunc),
    },
    disconnectRouteOptions: {
        integration: new integrations.WebSocketLambdaIntegration('DisconnectHandler', disconnectFunc)
    },
    defaultRouteOptions: {
      integration: new integrations.WebSocketLambdaIntegration('DefaultHandler', defaultFunc),
    },
    routeSelectionExpression: '$request.body.action',
});

Despite setting up the custom authorizer, when attempting to connect to the Websocket API, I receive a connection closure callback with error code 1006. However, upon checking the cloudwatch logs, there is no log group found for the custom authorizer lambda, indicating that it may not be invoked as intended.

This is how I establish the websocket connection:

ws = new WebSocket(`wss://${host}/${stage}?token=${authToken}`);

Prior to adding the custom authorizer, the websocket connection was successful and the API functioned correctly.

I have verified that the custom authorizer lambda can be executed using the Test function in the console, and logs are generated accordingly.

Here is the implementation of the authorizer handler:

import { APIGatewayRequestAuthorizerEvent, APIGatewayAuthorizerResult } from 'aws-lambda';

const secret = process.env.API_SECRET ?? '';

export const handler = async (event: APIGatewayRequestAuthorizerEvent): Promise<APIGatewayAuthorizerResult> => {

    console.log(`Event: ${JSON.stringify(event)}`);

    const query = event.queryStringParameters ?? { token: 'NONE' };
    const token = query['token'];

    console.log(`Query: ${JSON.stringify(query)}`);

    if (token === secret) {
        console.log(`Allowed`);
        return generatePolicy('user', 'Allow', event.methodArn);
    } else {
        console.log(`Denied`);
        return generatePolicy('user', 'Deny', event.methodArn);
    }

};

function generatePolicy(principalId: string, effect: string, resource: string) {
    return {
        principalId,
        policyDocument: {
        Version: '2012-10-17',
        Statement: [
            {
                Action: 'execute-api:Invoke',
                Effect: effect,
                Resource: resource,
            },
        ],
        },
    };
}

What could be missing in order to get this custom authorizer functioning properly?

Answer №1

After some troubleshooting, I finally found the solution. To make it work, I made sure to include the identitySource argument in the declaration of WebSocketLambdaAuthorizer:

const authorizer = new WebSocketLambdaAuthorizer(
    "WebsocketAuth",
    authFunc,
    {
        identitySource: ['route.request.querystring.token']
    }
);

This step is crucial because without specifying the fields in the identitySource, the authorizer won't be triggered. By default, the identitySource is set to the Authorization header, which doesn't apply easily to websocket connections.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

To collapse a div in an HTML Angular environment, the button must be clicked twice

A series of divs in my code are currently grouped together with expand and collapse functionality. It works well, except for the fact that I have to click a button twice in order to open another div. Initially, the first click only collapses the first div. ...

The data type 'unknown' cannot be assigned to the type 'any[]', 'Iterable<any>', or (Iterable<any> & any[])

I have been working on creating a custom search filter in my Angular project, and it was functioning properly. However, I encountered an error in my Visual Studio Code. In my previous project, everything was working fine until I updated my CLI, which resul ...

Dynamically apply classes in Angular using ngClass

Help needed with setting a class dynamically. Any guidance is appreciated. Below is the class in my SCSS file: .form-validation.invalid { border: 2px solid red } In my ts file, there's a variable named isEmailValid. When this variable is set to ...

Type Vue does not contain the specified property

I am encountering an issue where I am using ref to retrieve a value, but I keep receiving the error message "Property 'value' does not exist on type 'Vue'". Below is the code snippet causing the problem: confirmPasswordRules: [ ...

The sequence of events in React Native following a navigation.navigate call

Seeking suggestions and advice, I currently have the following 2 lines of code within a react native expo component: this.props.navigation.navigate("App"); patchUser(this.state.dataSource.userInfo.username, this.state.dataSource.userInfo.firstN ...

Transferring a file from the /tmp directory on Amazon Lambda to an S3 bucket using Node.js

My current project involves developing a straightforward screenshot program using Amazon Lambda. The program will take a snapshot of a specified URL and store it in JSON format like this: { "site": "www.example.com", "width": "320", "height": "480" ...

Obtaining Axios response header in a Typescript environment

I am currently working on a rest call that may return a header that I need to store. In order to do this, I have to first check if the header is present before storing it. Here is how I approached it: private getHeader(response: AxiosResponse) { if (r ...

Can you explain the significance of { 0: T } in this particular type definition?

I stumbled upon this type declaration in my codebase which is meant for non-empty arrays: type NonEmptyArray<T> = T[] & { 0: T } and it functions as expected: const okay: NonEmptyArray<number> = [1, 2]; const alsoOkay: NonEmptyArray<n ...

Does Angular 8 development mode implement tree-shaking?

I am curious to know if tree-shaking occurs during Angular 8 development mode. When running the following command: ng build I understand that tree-shaking happens when I use the command below: ng build --optimization=true|false ...

How should one begin a new NativeScript-Vue project while implementing Typescript support in the most effective manner?

Is it possible to incorporate Typescript into Vue instance methods? I found guidance on the blog page of nativescript-vue.org. Whenever I initiate a new nativescript-vue project using vue init nativescript-vue/vue-cli-template <project-name>, some w ...

Managing animations with multiple components in Angular 2+

I am currently developing an Angular application that will utilize a series of Modals in a wizard-style setup. For this project, I am utilizing the Angular-cli tool. Below is the code snippet showing how I have set up my animations: animations:[ t ...

The type 'Requireable<string>' cannot be matched with the type 'Validator<"horizontal" | "vertical" | undefined>'

code import * as React from 'react'; import * as PropTypes from 'prop-types'; interface ILayoutProps { dir?: 'horizontal' | 'vertical' }; const Layout: React.FunctionComponent<ILayoutProps> = (props) => ...

Implementing TypeScript inheritance by exporting classes and modules

I've been struggling with TypeScript's inheritance, it seems unable to resolve the class I'm trying to inherit. lib/classes/Message.class.ts ///<reference path='./def/lib.d.ts'/> ///<reference path='./def/node.d.ts& ...

Steps to develop a sub-route specifically for a single word

Take a look at this code: {path : 'recipes', component:RecipesComponent, children:[ {path:':id', component:RecipeDetailComponent}, {path:':new', component:NewRecipeComponent } ]}, No matter which link you use: h ...

The function in Angular 5/Typescript disappears when attempting to call it from within another function

After importing D3 into my component, I encounter an issue when trying to assign a layout to the D3.layout property. Strangely, although the layout property is present in the console output of my D3 object, it seems to be unknown when I attempt to call i ...

Introducing a delay in an observable causes incomplete data to be received in Angular using rxjs

Currently, I am facing an issue in my code where I am trying to introduce a delay using timer(500). However, the problem is that it is only returning partial data. Instead of the expected 17 fields, it is only returning 2 fields. Below is my code snippet f ...

"What sets apart the usage of `import * as Button` from `import {Button}`

As a newcomer to Typescript, I am facing an issue while trying to import a react-bootstrap Button. In scenario 1: import {Button} from 'react-bootstrap/lib/Button' In scenario 2: import * as Button from 'react-bootstrap/lib/Button' B ...

Error: Code cannot be executed because the variable "sel" has not been defined in the HTML element

Every time I try to click on the div, I encounter an error message stating 'Uncaught ReferenceError: sel is not defined at HTMLDivElement.onclick' I am currently developing with Angular 8 and this error keeps popping up. I have read through simil ...

Tips for effectively packaging the React 17 library alongside the latest JSX transformation feature as an ES Module

I am currently in the process of creating a basic library consisting of React components that I intend to publish as an ES Module package for NPM. With the utilization of React 17, I have incorporated the new JSX transform into my code. To generate the ES ...

What is the process of including items in an Array?

I have been attempting to use the push method to add elements to an Array in Typescript, but strangely it doesn't seem to be working. The array just stays empty. Here's the code I have: list: Array<int> = Array(10) for(le ...