我正在尝试为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,
},
],
},
};
}
我缺少什么来使这个自定义授权程序工作?
1条答案
按热度按时间2o7dmzc51#
我想明白了。我必须将
identitySource
参数添加到WebSocketLambdaAuthorizer
声明中:这是必需的,因为显然如果
identitySource
中的字段不存在,则不会调用授权器,并且默认的identitySource
是Authorization
头,这对于WebSocket连接来说不容易设置。