API 创新不会触发 AWS API Gateway 的基于自定义请求的 lambda 授权方
Posted
技术标签:
【中文标题】API 创新不会触发 AWS API Gateway 的基于自定义请求的 lambda 授权方【英文标题】:Custom request-based lambda authorizer for AWS API Gateway is not triggered for API innovations 【发布时间】:2020-12-19 14:04:00 【问题描述】:按照文档 (https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) 为我的 AWS API Gateway 创建了一个简单的基于请求的简单授权方
在测试授权方时(使用虚拟设置验证授权标头中是否包含密钥“test”)授权方工作正常,但在直接从端点调用 API 时,根本没有调用授权方,我得到了我的 API响应(应该被阻止,因为没有传递标头)。
使用无效密钥的授权人测试:得到预期的 401
使用有效密钥的授权人测试:预期为 200
从网页直接调用API端点成功:
我的 API 网关资源策略只想限制来自特定 IP 范围的调用:
"Version": "2012-10-17",
"Statement": [
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:111111111111:6mm9kw17uf/*/*/*"
,
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:111111111111:6mm9kw17uf/*/*/*",
"Condition":
"NotIpAddress":
"aws:SourceIp": "XXXXXXX"
]
授权人 Lambda 代码:
exports.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;
// 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 restApiId = apiGatewayArnTmp[0];
var stage = apiGatewayArnTmp[1];
var method = apiGatewayArnTmp[2];
var resource = '/'; // root 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.Authorization === "test")
callback(null, generateAllow('me', event.methodArn));
else
callback("Unauthorized");
// Help 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';
policyDocument.Statement = [];
var statementOne = ;
statementOne.Action = 'execute-api:Invoke';
statementOne.Effect = effect;
statementOne.Resource = resource;
policyDocument.Statement[0] = statementOne;
authResponse.policyDocument = policyDocument;
return authResponse;
var generateAllow = function(principalId, resource)
return generatePolicy(principalId, 'Allow', resource);
var generateDeny = function(principalId, resource)
return generatePolicy(principalId, 'Deny', resource);
我已经尝试过的:
-
我已经在添加授权方后再次重新部署了 API。
我正在通过邮递员和网络浏览器进行测试,而不是网关测试,因为它会绕过授权者。
【问题讨论】:
【参考方案1】:我尝试使用我自己的 API 网关复制该问题,但我没有发现您的 lambda 函数有任何问题。它按预期工作。
授权调用示例:
curl -i -w "\n" --http1.1 -H 'Authorization: test' https://xxxxx.execute-api.us-east-1.amazonaws.com/dev/helloworld
HTTP/1.1 200 OK
Date: Sun, 06 Sep 2020 11:22:30 GMT
Content-Type: application/json
Content-Length: 67
Connection: keep-alive
x-amzn-RequestId: 4213f276-737c-4481-bbac-3c4ecd767b6f
x-amz-apigw-id: ScPyeFInoAMFYKg=
X-Amzn-Trace-Id: Root=1-5f54c676-9e0c8bbe6093d8889f6b2035;Sampled=0
"statusCode": 200,
"message": "Hello from API Gateway!"
非授权调用示例:
curl -i -w "\n" --http1.1 -H 'Authorization: invalid' https://xxxx.execute-api.us-east-1.amazonaws.com/dev/helloworld
HTTP/1.1 401 Unauthorized
Date: Sun, 06 Sep 2020 11:25:36 GMT
Content-Type: application/json
Content-Length: 26
Connection: keep-alive
x-amzn-RequestId: 42a1d47c-aab5-4b72-b8eb-469fed383b26
x-amzn-ErrorType: UnauthorizedException
x-amz-apigw-id: ScQPpFUwoAMFRdA=
"message":"Unauthorized"
提供的无标题值示例:
curl -i -w "\n" --http1.1 https://xxxx.execute-api.us-east-1.amazonaws.com/dev/helloworld
HTTP/1.1 401 Unauthorized
Date: Sun, 06 Sep 2020 11:26:15 GMT
Content-Type: application/json
Content-Length: 26
Connection: keep-alive
x-amzn-RequestId: 982944f2-ac1d-4eee-8776-7bfa76314d2b
x-amzn-ErrorType: UnauthorizedException
x-amz-apigw-id: ScQVwGmpoAMFfSA=
"message":"Unauthorized"
需要考虑的事项:
-
当您将授权方添加到您的 api 方法时,您必须再次部署阶段。
新的授权人开始工作需要时间。因此,在启用它并创建新阶段后,必须等待几分钟才能开始工作
【讨论】:
嗨,Marcin Weird,因为我确实再次部署了舞台并等待了很长时间,但它仍然无法正常工作。我是否需要从 API 网关添加任何其他内容?因为由于某种原因它没有被触发。我需要更新资源政策吗? @KumarVivek 您是否将您的 lambda 函数指定为您的helloworld
资源的 GET 方法的授权?仅仅创建授权者是不够的。您必须将它附加到您希望使用它的每个方法和资源。
@KumarVivek 另外,每次更改 API 后,不要忘记重新部署阶段。
我好像忘记了,我试试看。以上是关于API 创新不会触发 AWS API Gateway 的基于自定义请求的 lambda 授权方的主要内容,如果未能解决你的问题,请参考以下文章
使用 Learner Lab - 使用 API Gateway 触发 AWS Lambda
使用代理集成通过 API Gateway 触发 AWS Lambda
AWS SAM 模板 - 定义由 API Gateway 触发的 SQS 队列