Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Contrôlez l'accès aux WebSocket API avec les AWS Lambda autorisateurs REQUEST
Une fonction d'autorisation Lambda dans les WebSocket API est similaire à celle des API REST, avec les exceptions suivantes :
-
Vous pouvez uniquement utiliser une fonction de mécanisme d'autorisation Lambda pour la route $connect
.
-
Vous ne pouvez pas utiliser de variables de chemin (event.pathParameters
), car le chemin d'accès est fixe.
-
event.methodArn
est différent de son équivalent de l'API REST, car il ne possède pas de méthode HTTP. Dans le cas de $connect
, methodArn
se termine par "$connect"
:
arn:aws:execute-api:region
:account-id
:api-id
/stage-name
/$connect
-
Les variables de contexte dans event.requestContext
sont différentes de celles des API REST.
L'exemple suivant montre une entrée dans un REQUEST
autorisateur pour une WebSocket API :
{
"type": "REQUEST",
"methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/default/$connect",
"headers": {
"Connection": "upgrade",
"content-length": "0",
"HeaderAuth1": "headerValue1",
"Host": "abcdef123.execute-api.us-east-1.amazonaws.com",
"Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits",
"Sec-WebSocket-Key": "...",
"Sec-WebSocket-Version": "13",
"Upgrade": "websocket",
"X-Amzn-Trace-Id": "...",
"X-Forwarded-For": "...",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"Connection": [
"upgrade"
],
"content-length": [
"0"
],
"HeaderAuth1": [
"headerValue1"
],
"Host": [
"abcdef123.execute-api.us-east-1.amazonaws.com"
],
"Sec-WebSocket-Extensions": [
"permessage-deflate; client_max_window_bits"
],
"Sec-WebSocket-Key": [
"..."
],
"Sec-WebSocket-Version": [
"13"
],
"Upgrade": [
"websocket"
],
"X-Amzn-Trace-Id": [
"..."
],
"X-Forwarded-For": [
"..."
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
"queryStringParameters": {
"QueryString1": "queryValue1"
},
"multiValueQueryStringParameters": {
"QueryString1": [
"queryValue1"
]
},
"stageVariables": {},
"requestContext": {
"routeKey": "$connect",
"eventType": "CONNECT",
"extendedRequestId": "...",
"requestTime": "19/Jan/2023:21:13:26 +0000",
"messageDirection": "IN",
"stage": "default",
"connectedAt": 1674162806344,
"requestTimeEpoch": 1674162806345,
"identity": {
"sourceIp": "..."
},
"requestId": "...",
"domainName": "abcdef123.execute-api.us-east-1.amazonaws.com",
"connectionId": "...",
"apiId": "abcdef123"
}
}
L'exemple de fonction d'autorisation Lambda suivant est une WebSocket version de la fonction d'autorisation Lambda pour les API REST dans : Exemples supplémentaires de fonctions d'autorisation Lambda
- Node.js
// A simple REQUEST authorizer example to demonstrate how to use request
// parameters to allow or deny a request. In this example, a request is
// authorized if the client-supplied HeaderAuth1 header and QueryString1 query parameter
// in the request context match the specified values of
// of 'headerValue1' and 'queryValue1' respectively.
export const handler = function(event, context, callback) {
console.log('Received event:', JSON.stringify(event, null, 2));
// Retrieve request parameters from the Lambda function input:
var headers = event.headers;
var queryStringParameters = event.queryStringParameters;
var stageVariables = event.stageVariables;
var requestContext = event.requestContext;
// Parse the input for the parameter values
var tmp = event.methodArn.split(':');
var apiGatewayArnTmp = tmp[5].split('/');
var awsAccountId = tmp[4];
var region = tmp[3];
var ApiId = apiGatewayArnTmp[0];
var stage = apiGatewayArnTmp[1];
var route = apiGatewayArnTmp[2];
// Perform authorization to return the Allow policy for correct parameters and
// the 'Unauthorized' error, otherwise.
var authResponse = {};
var condition = {};
condition.IpAddress = {};
if (headers.HeaderAuth1 === "headerValue1"
&& queryStringParameters.QueryString1 === "queryValue1") {
callback(null, generateAllow('me', event.methodArn));
} else {
callback("Unauthorized");
}
}
// Helper function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
// Required output:
var authResponse = {};
authResponse.principalId = principalId;
if (effect && resource) {
var policyDocument = {};
policyDocument.Version = '2012-10-17'; // default version
policyDocument.Statement = [];
var statementOne = {};
statementOne.Action = 'execute-api:Invoke'; // default action
statementOne.Effect = effect;
statementOne.Resource = resource;
policyDocument.Statement[0] = statementOne;
authResponse.policyDocument = policyDocument;
}
// Optional output with custom properties of the String, Number or Boolean type.
authResponse.context = {
"stringKey": "stringval",
"numberKey": 123,
"booleanKey": true
};
return authResponse;
}
var generateAllow = function(principalId, resource) {
return generatePolicy(principalId, 'Allow', resource);
}
var generateDeny = function(principalId, resource) {
return generatePolicy(principalId, 'Deny', resource);
}
- Python
# A simple REQUEST authorizer example to demonstrate how to use request
# parameters to allow or deny a request. In this example, a request is
# authorized if the client-supplied HeaderAuth1 header and QueryString1 query parameter
# in the request context match the specified values of
# of 'headerValue1' and 'queryValue1' respectively.
import json
def lambda_handler(event, context):
print(event)
# Retrieve request parameters from the Lambda function input:
headers = event['headers']
queryStringParameters = event['queryStringParameters']
stageVariables = event['stageVariables']
requestContext = event['requestContext']
# Parse the input for the parameter values
tmp = event['methodArn'].split(':')
apiGatewayArnTmp = tmp[5].split('/')
awsAccountId = tmp[4]
region = tmp[3]
ApiId = apiGatewayArnTmp[0]
stage = apiGatewayArnTmp[1]
route = apiGatewayArnTmp[2]
# Perform authorization to return the Allow policy for correct parameters
# and the 'Unauthorized' error, otherwise.
authResponse = {}
condition = {}
condition['IpAddress'] = {}
if (headers['HeaderAuth1'] ==
"headerValue1" and queryStringParameters["QueryString1"] == "queryValue1"):
response = generateAllow('me', event['methodArn'])
print('authorized')
return json.loads(response)
else:
print('unauthorized')
return 'unauthorized'
# Help function to generate IAM policy
def generatePolicy(principalId, effect, resource):
authResponse = {}
authResponse['principalId'] = principalId
if (effect and resource):
policyDocument = {}
policyDocument['Version'] = '2012-10-17'
policyDocument['Statement'] = []
statementOne = {}
statementOne['Action'] = 'execute-api:Invoke'
statementOne['Effect'] = effect
statementOne['Resource'] = resource
policyDocument['Statement'] = [statementOne]
authResponse['policyDocument'] = policyDocument
authResponse['context'] = {
"stringKey": "stringval",
"numberKey": 123,
"booleanKey": True
}
authResponse_JSON = json.dumps(authResponse)
return authResponse_JSON
def generateAllow(principalId, resource):
return generatePolicy(principalId, 'Allow', resource)
def generateDeny(principalId, resource):
return generatePolicy(principalId, 'Deny', resource)
Pour configurer la fonction Lambda précédente en tant que fonction d'REQUESTautorisation pour une WebSocket API, suivez la même procédure que pour les API REST.
Pour configurer la route $connect
afin qu'elle utilise ce mécanisme d'autorisation Lambda dans la console, sélectionnez ou créez la route $connect
. Dans la section Paramètres de la demande de route, choisissez Modifier. Sélectionnez votre mécanisme d'autorisation dans le menu déroulant Autorisation, puis choisissez Enregistrer les modifications.
Pour tester le mécanisme d'autorisation, vous devez créer une nouvelle connexion. La modification du mécanisme d'autorisation dans $connect
n'affecte pas le client déjà connecté. Lorsque vous vous connectez à votre WebSocket API, vous devez fournir des valeurs pour toutes les sources d'identité configurées. Par exemple, vous pouvez vous connecter en envoyant une chaîne de requête et un en-tête en utilisant wscat
comme dans l'exemple suivant :
wscat -c 'wss://myapi.execute-api.us-east-1.amazonaws.com/beta?QueryString1=queryValue1' -H HeaderAuth1:headerValue1
Si vous tentez de vous connecter sans valeur d'identité valide, vous recevrez une réponse 401
:
wscat -c wss://myapi.execute-api.us-east-1.amazonaws.com/beta
error: Unexpected server response: 401