mas*_*azi 6 aws-cloudformation aws-lambda aws-api-gateway aws-sam
我在 SAM 中使用 API Gateway 创建了一个 Lambda 函数,然后部署了它并且它按预期工作。在 API Gateway 中我使用了HttpApinot REST API。
然后,我想添加一个具有简单响应的 Lambda 授权者。因此,我遵循了 SAM 和 API Gateway 文档,并得出了下面的代码。
当我调用该路线时,items-list它现在返回401 Unauthorized,这是预期的。
myappauth但是,当我添加带有 value 的标头时"test-token-abc",我得到一个500 Internal Server Error.
我检查了此页面,但似乎列出的所有步骤都可以https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-http-lambda-integrations/
我按照以下说明启用了 API 网关的日志记录:https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-logging.html
但我得到的只是这样的(编辑了我的 IP 和请求 ID):
[MY-IP] - - [07/Jul/2021:08:24:06 +0000] "GET GET /items-list/{userNumber} HTTP/1.1" 500 35 [REQUEST-ID]
(也许我可以配置记录器,使其打印更有意义的错误消息?编辑:我尝试添加$context.authorizer.error到日志,但它不打印任何特定的错误消息,只打印破折号-:)
我还检查了 Lambda 函数的日志,那里没有任何内容(所有日志都是从我添加授权者之前开始的)。那么,我做错了什么?
这是我使用 部署的 Lambda Authorizer 函数,当我使用带有标头sam deploy的单独测试它时,它可以工作:eventmyappauth
exports.authorizer = async (event) => {
let response = {
"isAuthorized": false,
};
if (event.headers.myappauth === "test-token-abc") {
response = {
"isAuthorized": true,
};
}
return response;
};
Run Code Online (Sandbox Code Playgroud)
template.yml这是我部署使用的SAM sam deploy:
AWSTemplateFormatVersion: 2010-09-09
Description: >-
myapp-v1
Transform:
- AWS::Serverless-2016-10-31
Globals:
Function:
Runtime: nodejs14.x
MemorySize: 128
Timeout: 100
Environment:
Variables:
MYAPP_TOKEN: "test-token-abc"
Resources:
MyAppAPi:
Type: AWS::Serverless::HttpApi
Properties:
FailOnWarnings: true
Auth:
Authorizers:
MyAppLambdaAuthorizer:
AuthorizerPayloadFormatVersion: "2.0"
EnableSimpleResponses: true
FunctionArn: !GetAtt authorizerFunction.Arn
FunctionInvokeRole: !GetAtt authorizerFunctionRole.Arn
Identity:
Headers:
- myappauth
DefaultAuthorizer: MyAppLambdaAuthorizer
itemsListFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/v1-handlers.itemsList
Description: A Lambda function that returns a list of items.
Policies:
- AWSLambdaBasicExecutionRole
Events:
Api:
Type: HttpApi
Properties:
Path: /items-list/{userNumber}
Method: get
ApiId: MyAppAPi
authorizerFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/v1-handlers.authorizer
Description: A Lambda function that authorizes requests.
Policies:
- AWSLambdaBasicExecutionRole
Run Code Online (Sandbox Code Playgroud)
用户 @petey 建议我尝试在授权者函数中返回 IAM 策略,因此我在 中更改EnableSimpleResponses为,然后按如下所示更改了我的函数,但得到了相同的结果:falsetemplate.yml
exports.authorizer = async (event) => {
let response = {
"principalId": "my-user",
"policyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Action": "execute-api:Invoke",
"Effect": "Deny",
"Resource": event.routeArn
}]
}
};
if (event.headers.myappauth == "test-token-abc") {
response = {
"principalId": "my-user",
"policyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": event.routeArn
}]
}
};
}
return response;
};
Run Code Online (Sandbox Code Playgroud)
mas*_*azi 10
我将回答我自己的问题,因为我已经解决了这个问题,我希望这能帮助那些将要在 API Gateway 中使用新的“HTTP API”格式的人,因为目前还没有很多教程;您在网上找到的大多数示例都是针对较旧的 API 网关标准,亚马逊将其称为“REST API”。(如果你想知道两者的区别,请看这里)。
主要问题在于官方文档中提供的示例。他们有:
MyLambdaRequestAuthorizer:
FunctionArn: !GetAtt MyAuthFunction.Arn
FunctionInvokeRole: !GetAtt MyAuthFunctionRole.Arn
Run Code Online (Sandbox Code Playgroud)
问题在于,该模板将创建一个名为 的新角色MyAuthFunctionRole,但该角色不会附加所有必要的策略!
我在官方文档中错过的关键部分是这一段:
您必须使用函数的资源策略或 IAM 角色授予 API Gateway 调用 Lambda 函数的权限。在此示例中,我们更新该函数的资源策略,以便它授予 API Gateway 调用我们的 Lambda 函数的权限。
以下命令授予 API Gateway 调用您的 Lambda 函数的权限。如果 API Gateway 无权调用您的函数,客户端会收到 500 内部服务器错误。
解决这个问题的最佳方法是在 SAM 中实际包含 Role 定义template.yml,如下Resources:
MyAuthFunctionRole
Type: AWS::IAM::Role
Properties:
# [... other properties...]
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- apigateway.amazonaws.com
Action:
- 'sts:AssumeRole'
Policies:
# here you will put the InvokeFunction policy, for example:
- PolicyName: MyPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: 'lambda:InvokeFunction'
Resource: !GetAtt MyAuthFunction.Arn
Run Code Online (Sandbox Code Playgroud)
您可以在此处查看有关角色的各种属性的描述:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html
解决此问题的另一种方法是在 AWS 控制台中单独创建一个具有InvokeFunction权限的新策略,然后在部署后将该策略附加到MyAuthFunctionRoleSAM 创建的策略。现在授权者将按预期工作。
另一种策略是预先创建一个新角色,该角色具有具有InvokeFunction权限的策略,然后将该角色的内容复制并粘贴arn到 SAM 中template.yml:
MyLambdaRequestAuthorizer:
FunctionArn: !GetAtt MyAuthFunction.Arn
FunctionInvokeRole: arn:aws:iam::[...]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2239 次 |
| 最近记录: |