AWS Cloudformation 将 API 密钥链接到 API 网关
Posted
技术标签:
【中文标题】AWS Cloudformation 将 API 密钥链接到 API 网关【英文标题】:AWS Cloudformation Link API Key to API Gateway 【发布时间】:2019-01-15 03:03:50 【问题描述】:我尝试通过 SAM 部署以下 Cloudformation 模板。此模板正确地创建了 DynamoDB 表、API 密钥、Lambda 函数和 API 网关,但我无法弄清楚我需要在模板中指定什么才能将 API KEY 与 API 网关关联。
我发现很多 sn-ps 显示了部分示例,但我正在努力将它们拼凑在一起。
提前谢谢你,
丹尼
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Parameters:
TableName:
Type: String
Default: 'influencetabletest'
Description: (Required) The name of the new DynamoDB table Minimum 3 characters
MinLength: 3
MaxLength: 50
AllowedPattern: ^[A-Za-z-]+$
ConstraintDescription: 'Required parameter. Must be characters only. No numbers allowed.'
CorsOrigin:
Type: String
Default: '*'
Description: (Optional) Cross-origin resource sharing (CORS) Origin. You can specify a single origin, all "*" or leave empty and no CORS will be applied.
MaxLength: 250
Conditions:
IsCorsDefined: !Not [!Equals [!Ref CorsOrigin, '']]
Resources:
ApiKey:
Type: AWS::ApiGateway::ApiKey
DependsOn:
- ApiGetter
Properties:
Name: "TestApiKey"
Description: "CloudFormation API Key V1"
Enabled: "true"
ApiGetter:
Type: AWS::Serverless::Api
Properties:
StageName: prd
DefinitionBody:
swagger: 2.0
info:
title:
Ref: AWS::StackName
paths:
/getdynamicprice:
post:
responses:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:$AWS::Region:lambda:path/2015-03-31/functions/$LambdaGetter.Arn/invocations
LambdaGetter:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./index.js
Handler: index.handler
Runtime: nodejs8.10
Environment:
Variables:
TABLE_NAME: !Ref TableName
IS_CORS: IsCorsDefined
CORS_ORIGIN: !Ref CorsOrigin
PRIMARY_KEY: !Sub $TableNameId
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref TableName
Events:
Api:
Type: Api
Properties:
Path: /getdynamicprice
Method: POST
RestApiId: !Ref ApiGetter
DynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: !Ref TableName
AttributeDefinitions:
-
AttributeName: !Sub "$TableNameId"
AttributeType: "S"
KeySchema:
-
AttributeName: !Sub "$TableNameId"
KeyType: "HASH"
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
Outputs:
ApiKeyID:
Value: !Ref ApiKey
ApiUrl:
Value: !Sub https://$ApiGetter.execute-api.$AWS::Region.amazonaws.com/prod/getdynamicprice
Description: The URL of the API Gateway you invoke to get your dynamic pricing result.
DynamoDBTableArn:
Value: !GetAtt DynamoDBTable.Arn
Description: The ARN of your DynamoDB Table
DynamoDBTableStreamArn:
Value: !GetAtt DynamoDBTable.StreamArn
Description: The ARN of your DynamoDB Table Stream
【问题讨论】:
嗨@Denny,您如何在SAM 中启用APIkeyRequried
属性?因为在将apikey
附加到apiplan
之后,您需要启用此属性才能在请求中发送标头字符串吗?
【参考方案1】:
编辑(2020 年 4 月 22 日):现在似乎使用 AWS SAM 完成所有这些工作。请看下面的答案
这是一个示例模板,其中我已将我的 API 连接到 API 密钥。但这只是可能的,因为我使用的是usage plans
。我相信这是 API 密钥的主要目的。 API gateway usage plan
ApiKey:
Type: AWS::ApiGateway::ApiKey
Properties:
Name: !Join ["", ["Ref": "AWS::StackName", "-apikey"]]
Description: "CloudFormation API Key V1"
Enabled: true
GenerateDistinctId: false
ApiUsagePlan:
Type: "AWS::ApiGateway::UsagePlan"
Properties:
ApiStages:
- ApiId: !Ref <API resource name>
Stage: !Ref <stage resource name>
Description: !Join [" ", ["Ref": "AWS::StackName", "usage plan"]]
Quota:
Limit: 2000
Period: MONTH
Throttle:
BurstLimit: 10
RateLimit: 10
UsagePlanName: !Join ["", ["Ref": "AWS::StackName", "-usage-plan"]]
ApiUsagePlanKey:
Type: "AWS::ApiGateway::UsagePlanKey"
Properties:
KeyId: !Ref <API key>
KeyType: API_KEY
UsagePlanId: !Ref ApiUsagePlan
如果没有使用计划,似乎没有办法做到这一点。
【讨论】:
感谢您的回复。我觉得我越来越近了。我现在收到一个错误,即在 UsagePlan 下找不到 API 阶段。我将stage设置为prd,也就是ApiGetter下的stagename。也许这指的是别的东西? 我想跟进并感谢您。结果是两件事。我为 提供了不正确的值,我需要将 DependsOn 添加到 ApiKey、ApiUsagePlan 和 ApiUsagePlanKey 以确保它们以正确的顺序创建。 很高兴能帮上忙 +Upvote.@ASR 在您的帮助下,我创建了 api 密钥并将计划附加到特定阶段。但我对ApikeyRequired
财产感到震惊。我如何在 SAM 中启用它?在 cloudformation 中,我们在 AWS::ApiGateway::Method
中有此属性,但我不知道它在 SAM 中的位置。我试过这样但没有运气***.com/questions/52936126/…
您无法取消 API 密钥与使用计划的关联,因为 API 密钥与安全性无关,而更多地与计量访问有关。 AWS 在docs.aws.amazon.com/apigateway/latest/developerguide/… 中的“API 密钥和使用计划的最佳实践”部分中很好地讨论了这一点。【参考方案2】:
我确实尝试了 ASR 的建议,但最终采用了一种更简单的方法。 AWS SAM(无服务器应用程序模型)包含无需使用 ApiGateway 类型资源的预打包处理。
要创建一个需要在标头中包含授权令牌的阶段的 API 网关,您应该使用以下简化代码:
Resources:
ApiGatewayEndpoint:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Auth:
ApiKeyRequired: true
UsagePlan:
CreateUsagePlan: PER_API
UsagePlanName: GatewayAuthorization [any name you see fit]
LambdaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: lambda.handler
Runtime: python3.7
Timeout: 30
CodeUri: .
Events:
PostEvent:
Type: Api
Properties:
Path: /content
Method: POST
RequestParameters:
- method.request.header.Authorization:
Required: true
Caching: true
RestApiId:
Ref: ApiGatewayEndpoint [The logical name of your gateway endpoint above]
元素:
Auth:
ApiKeyRequired: true
UsagePlan:
CreateUsagePlan: PER_API
的诀窍是什么。 Cloudformation 为您处理管道,即。 Api Key、UsagePlan 和 UsagePlanKey 是自动创建和绑定的。
尽管这些文档绝对不是同类中最好的,但它们确实提供了一些额外的信息:https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-resources-and-properties.html
【讨论】:
当你自动说的时候,你的意思是你强调的那个声明就足够了,剩下的SAM
就够了吗?还是先用 CFN 创建密钥、使用计划等然后附加?
@ASR 是的,突出显示的声明就足够了,其他一切都由 SAM 完成
老兄,你救了我,如果可以的话,我会给你 100 个代表以上是关于AWS Cloudformation 将 API 密钥链接到 API 网关的主要内容,如果未能解决你的问题,请参考以下文章
将现有 AWS Lambda 和 API Gateway 导出到 Cloudformation 模板
将特定 AWS API Gateway 阶段连接到 CloudFormation 模板中的特定 Lambda 别名
如何使用 CloudFormation 模板更新现有 AWS API Gateway
如何使用 AWS CloudFormation 在 AWS API Gateway 上应用安全策略?