Steuern Sie den Zugriff auf WebSocket APIs mit AWS Lambda REQUEST-Autorisierern - APIAmazon-Gateway

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Steuern Sie den Zugriff auf WebSocket APIs mit AWS Lambda REQUEST-Autorisierern

Eine Lambda-Autorisierungsfunktion in WebSocket APIs ähnelt der für REST-APIs, mit den folgenden Ausnahmen:

  • Sie können für die $connect-Route nur eine Lambda-Genehmiger-Funktion verwenden.

  • Sie können keine Pfadvariablen (event.pathParameters) verwenden, da der Pfad fest ist.

  • event.methodArn unterscheidet sich von seinem REST API-Äquivalent, da es über keine HTTP-Methode verfügt. Im Fall von $connect endet methodArn mit "$connect":

    arn:aws:execute-api:region:account-id:api-id/stage-name/$connect
  • Die Kontextvariablen in event.requestContext unterscheiden sich von denen für REST-APIs.

Das folgende Beispiel zeigt eine Eingabe für einen REQUEST Autorisierer für eine API: WebSocket

{ "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" } }

Die folgende Lambda-Autorisierungsfunktion ist eine WebSocket Version der Lambda-Autorisierungsfunktion für REST-APIs in: Zusätzliche Beispiele für Lambda-Authorizer-Funktionen

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)

Gehen Sie genauso vor wie bei REST-APIs, um die vorherige Lambda-Funktion als REQUEST Autorisierungsfunktion für eine WebSocket API zu konfigurieren.

Um die $connect-Route für die Verwendung dieses Lambda-Genehmigers in der Konsole zu konfigurieren, wählen Sie die $connect-Route oder erstellen diese. Wählen Sie im Abschnitt Route request settings (Einstellungen der Routenanforderung) die Option Edit (Bearbeiten) aus. Wählen Sie im Dropdown-Menü Authorization (Autorisierung) Ihren Autorisierer aus und wählen Sie dann Save changes (Änderungen speichern) aus.

Zum Testen des Genehmigers müssen Sie eine neue Verbindung erstellen. Wenn der Genehmiger in $connect geändert wird, hat dies keine Auswirkungen auf den bereits verbundenen Client. Wenn Sie eine Verbindung zu Ihrer WebSocket API herstellen, müssen Sie Werte für alle konfigurierten Identitätsquellen angeben. Beispielsweise können Sie eine Verbindung durch Senden einer gültigen Abfragezeichenfolge und eines gültigen Headers unter Verwendung von wscat wie im folgenden Beispiel herstellen:

wscat -c 'wss://myapi.execute-api.us-east-1.amazonaws.com/beta?QueryString1=queryValue1' -H HeaderAuth1:headerValue1

Bei dem Versuch, ohne einen gültigen Identitätswert eine Verbindung herzustellen, erhalten Sie eine 401-Antwort:

wscat -c wss://myapi.execute-api.us-east-1.amazonaws.com/beta error: Unexpected server response: 401