typescript - Anpassad auktorisator anropas inte för websocket connect-händelse
Jag försöker implementera en anpassad auktoriserare för en API Gateway Websocket API.
Jag har min anpassade auktoriserare deklarerad så här med 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',
});
När jag försöker ansluta till detta Websocket API får jag en callback för stängd anslutning med kod 1006. Men när jag kollar Cloudwatch-loggarna finns det ingen logggrupp för min anpassade auktoriserare, så det verkar som om lambda-funktionen inte anropas som förväntat.
Jag ansluter så här:
ws = new WebSocket(`wss://${host}/${stage}?token=${authToken}`);
Innan den anpassade auktoriseraren lades till lyckades websocket-anslutningen, och API:et fungerade som förväntat.
Jag kan köra den anpassade auktoriseraren lambda med Test-funktionen i konsolen, och loggar skapas som förväntat.
Här är implementeringen av auktoriseringshanteraren:
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,
},
],
},
};
}
Vad saknar jag för att få den här anpassade auktoriseraren att fungera?
Svar #1
Jag klurade ut det. Jag var tvungen att lägga till argumentet identitySource i WebSocketLambdaAuthorizer-deklarationen:
const authorizer = new WebSocketLambdaAuthorizer(
"WebsocketAuth",
authFunc,
{
identitySource: ['route.request.querystring.token']
}
);
Detta är nödvändigt, eftersom godkännaren tydligen inte kommer att anropas om fälten i identitySource inte är närvarande, och standard identitySource är Authorization-huvudet, vilket inte enkelt kan ställas in för websocket-anslutningar.
