【发布时间】:2022-03-16 03:09:35
【问题描述】:
我正在使用 AWS Serverless 创建一个支持 Lambda 函数的 API 网关。
我定义了以下资源和方法:
/projects
-> GET (should require API key)
-> OPTIONS (should not, since it is used for CORS preflight)
我遇到了 CORS 问题并需要 API 密钥。前端客户端代码在启动预检 CORS OPTIONS 请求时收到 403 Forbidden 错误,因为对于 OPTIONS 方法,AWS 管理控制台中的 API Key Required 设置为 True。
我想专门为 OPTIONS 请求禁用安全性,但为所有其他方法(GET、POST 等)保留它。这是我的资源定义(你可以看到我在 Auth 对象中设置了默认的 ApiKeyRequired: true:
MyApi:
Type: 'AWS::Serverless::Api'
Name: MyApi
Properties:
Auth:
AddDefaultAuthorizerToCorsPreflight: true
ApiKeyRequired: true # sets for all methods
Cors:
AllowCredentials: true
AllowHeaders: '"Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token"'
AllowMethods: '"POST,GET,OPTION"'
AllowOrigin: '"*"'
MaxAge: '"600"'
StageName: !Ref StageName
DefinitionBody:
swagger: 2.0
info:
title: !Sub API-Lambda-${StageName}
description: "API for MyApi"
version: "1.0.0"
paths:
/projects:
get:
produces:
- application/json
responses:
"200":
description: OK
x-amazon-apigateway-any-method:
produces:
- application/json
x-amazon-apigateway-integration:
httpMethod: post
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetAllProjectsFunction.Arn}/invocations
options:
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: 200 response
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,mode,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: when_no_match
requestTemplates:
application/json: "{\"statusCode\": 200}"
type: mock
/projects/{userId}:
get:
responses:
"200":
description: OK
x-amazon-apigateway-any-method:
produces:
- application/json
x-amazon-apigateway-integration:
httpMethod: post
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetProjectsForUserFunction.Arn}/invocations
options:
consumes:
- application/json
responses:
'200':
description: 200 response
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,mode,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: when_no_match
requestTemplates:
application/json: "{\"statusCode\": 200}"
type: mock
我知道Swagger documentation 表示我可以通过为每个资源方法添加security 对象来覆盖安全性。这个SO post 还建议我可以通过将security 对象设为空列表来禁用安全性。
但是,我尝试了以下方法:
options:
consumes:
- application/json
produces:
- application/json
security:
-
responses: ...
并且还简单地将 security 设为 None 对象:
options:
consumes:
- application/json
produces:
- application/json
security:
responses: ...
在这两种情况下,我在尝试使用 aws sam deploy 进行部署时都会收到以下错误:
等待创建变更集。错误:创建失败 堆栈的变更集:my-app,例如:Waiter ChangeSetCreateComplete 失败:服务员遇到终端故障状态状态:FAILED。 原因:转换 AWS::Serverless-2016-10-31 失败:内部 转换失败。
我的security 定义似乎是错误的。如何禁用资源的一种方法(即OPTIONS 方法)的安全性?
更新:
我使用以下语法获得了要部署的模板:
options:
consumes:
- application/json
produces:
- application/json
security:
- {}
responses:
但是,即使在部署之后,我的控制台中仍然有这个:
老实说,我现在不知所措,因为使用常规 AWS::ApiGateway::Method 资源很容易做到这一点(只需将 ApiKeyRequired 设置为 true)。
【问题讨论】:
标签: amazon-web-services swagger amazon-cloudformation aws-api-gateway aws-serverless