Warum gibt meine API-Gateway-Proxy-Ressource mit einem Lambda-Genehmiger, bei dem das Caching aktiviert ist, den HTTP 403-Fehler „User is not authorized to access this resource“ zurück?
Meine Amazon API Gateway-Proxy-Ressource mit einem AWS Lambda-Genehmiger, bei dem Caching aktiviert ist, gibt die folgende HTTP 403-Fehlermeldung zurück: „User is not authorized to access this resource“.
Kurzbeschreibung
Hinweis: API Gateway kann aus verschiedenen Gründen Fehler 403 User is not authorized to access this resource zurückgeben. Dieser Artikel behandelt 403-Fehler im Zusammenhang mit API Gateway-Proxy-Ressourcen mit einem Lambda-Genehmiger, für den nur das Caching aktiviert ist. Informationen zum Beheben anderer Arten von 403-Fehlern findest du unter Wie behebe ich HTTP-403-Fehler von API Gateway?
Die Ausgabe eines Lambda-Genehmigers gibt eine AWS Identity and Access Management (IAM, Identitäts- und Zugriffsmanagement)-Richtlinie an API Gateway zurück. Die IAM-Richtlinie enthält ein explizites API- „Resource“ -Element des API Gateways im folgenden Format:
"arn:aws:execute-api:<region>:<account>:<API_id>/<stage>/<http-method>/[<resource-path-name>/[<child-resources-path>]"
Wenn Genehmigungs-Caching auf einem Lambda-Genehmiger aktiviert ist, wird die zurückgegebene IAM-Richtlinie zwischengespeichert. Die zwischengespeicherte IAM-Richtlinie wird dann auf alle zusätzlichen API-Anforderungen angewendet, die innerhalb des angegebenen Time-to-Live-Zeitraums (TTL) des Caches gestellt werden.
Wenn die API eine Proxy-Ressource mit der gierigen Pfadvariablen {proxy+} hat, ist die erste Autorisierung erfolgreich. Alle zusätzlichen API-Anforderungen, die innerhalb des TTL-Zeitraums des Caches an einen anderen Pfad gestellt werden, schlagen fehl und geben den folgenden Fehler zurück:
„message“: „User is not authorized to access this resource“
Die zusätzlichen Anforderungen schlagen fehl, weil die Pfade nicht mit dem expliziten API-Element „Resource“ des API Gateways übereinstimmen, das in der zwischengespeicherten IAM-Richtlinie definiert ist.
Um das Problem zu beheben, kannst du den Code der Lambda-Genehmigerfunktion so ändern, dass stattdessen eine Platzhalterressource (*/*) in der Ausgabe zurückgegeben wird. Weitere Informationen findest du unter Ressourcen und Bedingungen für Lambda-Aktionen.
Hinweis: Um das Genehmiger-Caching zu aktivieren, muss der Genehmiger eine Richtlinie zurückgeben, die für alle Methoden in einem API-Gateway gilt. Der Code der Lambda-Genehmigerfunktion muss in der Ausgabe eine Platzhalterressource (*/*) zurückgeben, um alle Ressourcen zuzulassen. Die Cache-Richtlinie erwartet, dass derselbe Ressourcenpfad zwischengespeichert wird, es sei denn, du hast dieselbe Anforderung zweimal auf demselben Ressourcenpfad gestellt.
Lösung
Hinweis: Passe die Beispielcodeausschnitte für die Lambda-Genehmigerfunktion in diesem Artikel an deinen Anwendungsfall an.
In den folgenden Beispieleinrichtungen extrahieren die Lambda-Funktionen den id-Wert des API-Gateways aus dem Amazon-Ressourcennamen (ARN) der Methode („event.methodArn“). Dann definieren die Funktionen eine Platzhaltervariable „Resource“, indem sie die Pfade der Methode ARN mit dem id-Wert der API und einem Platzhalter (*/*) kombinieren.
Beispiel für einen tokenbasierten Funktionscode des Lambda-Genehmigers, der eine Platzhaltervariable „Resource“ zurückgibt
exports.handler = function(event, context, callback) { var token = event.authorizationToken; var tmp = event.methodArn.split(':'); var apiGatewayArnTmp = tmp[5].split('/'); // Create wildcard resource var resource = tmp[0] + ":" + tmp[1] + ":" + tmp[2] + ":" + tmp[3] + ":" + tmp[4] + ":" + apiGatewayArnTmp[0] + '/*/*'; switch (token) { case 'allow': callback(null, generatePolicy('user', 'Allow', resource)); break; case 'deny': callback(null, generatePolicy('user', 'Deny', resource)); break; case 'unauthorized': callback("Unauthorized"); // Return a 401 Unauthorized response break; default: callback("Error: Invalid token"); // Return a 500 Invalid token response } }; // Help function to generate an IAM policy var generatePolicy = function(principalId, effect, resource) { var authResponse = {}; authResponse.principalId = principalId; if (effect && resource) { var policyDocument = {}; policyDocument.Version = '2012-10-17'; policyDocument.Statement = []; var statementOne = {}; statementOne.Action = 'execute-api:Invoke'; 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; }
Beispielanforderung für einen parameterbasierten Funktionscode des Lambda-Genehmigers, der eine Platzhaltervariable „Resource“ zurückgibt
exports.handler = function(event, context, callback) { // Retrieve request parameters from the Lambda function input: var headers = event.headers; var queryStringParameters = event.queryStringParameters; var pathParameters = event.pathParameters; var stageVariables = event.stageVariables; // Parse the input for the parameter values var tmp = event.methodArn.split(':'); var apiGatewayArnTmp = tmp[5].split('/'); // Create wildcard resource var resource = tmp[0] + ":" + tmp[1] + ":" + tmp[2] + ":" + tmp[3] + ":" + tmp[4] + ":" + apiGatewayArnTmp[0] + '/*/*'; console.log("resource: " + resource); // if (apiGatewayArnTmp[3]) { // resource += apiGatewayArnTmp[3]; // } // 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" && stageVariables.StageVar1 === "stageValue1") { callback(null, generateAllow('me', resource)); } else { callback("Unauthorized"); } } // Help function to generate an IAM policy var generatePolicy = function(principalId, effect, resource) { // Required output: console.log("Resource in generatePolicy(): " + resource); 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; console.log("***Resource*** " + resource); policyDocument.Statement[0] = statementOne; console.log("***Generated Policy*** "); console.log(policyDocument); 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); }
Weitere Informationen zum Bearbeiten des Lambda-Funktionscodes findest du unter Bereitstellung von Lambda-Funktionen, die als .zip-Dateiarchive definiert sind.
Ähnliche Informationen
Relevanter Inhalt
- AWS OFFICIALAktualisiert vor 2 Jahren
- AWS OFFICIALAktualisiert vor 2 Jahren
- AWS OFFICIALAktualisiert vor 8 Monaten