自定义授权器未被调用用于WebSocket连接事件

omvjsjqw  于 2023-04-21  发布在  其他
关注(0)|答案(1)|浏览(79)

我正在尝试为API网关WebSocket API实现自定义授权器。
我使用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',
});

当我尝试连接到这个WebSocket API时,我得到了一个连接闭包回调,代码为1006。然而,当我检查cloudwatch日志时,我的自定义authroizer没有日志组,所以看起来好像lambda没有按预期被调用。
我这样连接:

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

在添加自定义授权器之前,WebSocket连接成功,API工作正常。
我能够使用控制台中的Test函数执行自定义授权器lambda,并按预期创建日志。
下面是授权处理程序的实现:

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,
            },
        ],
        },
    };
}

我缺少什么来使这个自定义授权程序工作?

2o7dmzc5

2o7dmzc51#

我想明白了。我必须将identitySource参数添加到WebSocketLambdaAuthorizer声明中:

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

这是必需的,因为显然如果identitySource中的字段不存在,则不会调用授权器,并且默认的identitySourceAuthorization头,这对于WebSocket连接来说不容易设置。

相关问题