.NET中带Serverless Annotations的AWS Lambda如何配置API Key验证?
为AWS Lambda Annotations项目配置API Key验证
我用AWS Lambda Annotations创建了一个空白无服务器应用,生成的serverless.template配置如下:
{ "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", "Description": "An AWS Serverless Application. This template is partially managed by Amazon.Lambda.Annotations (v1.0.0.0).", "Resources": { "MyAppFunctionsGetGenerated": { "Type": "AWS::Serverless::Function", "Metadata": { "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" ] }, "Properties": { "Runtime": "dotnet6", "CodeUri": ".", "MemorySize": 256, "Timeout": 30, "Policies": [ "AWSLambdaBasicExecutionRole" ], "PackageType": "Zip", "Handler": "MyApp::MyApp.Functions_Get_Generated::Get", "Events": { "RootGet": { "Type": "Api", "Properties": { "Path": "/", "Method": "GET" } } } } } }, "Outputs": { "ApiURL": { "Description": "API endpoint URL for Prod environment", "Value": { "Fn::Sub": "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/" } } } }
试过Stack Overflow上的旧方案(无Annotations的实现)都不生效,请问该如何配置才能让接口要求API Key验证?
解决方案
需要在serverless.template中添加API Key、Usage Plan资源,并修改API Event的配置,具体操作如下:
- 添加API Key资源
在Resources节点下新增一个API Key资源:
"MyApiKey": { "Type": "AWS::ApiGateway::ApiKey", "Properties": { "Name": "MyAppApiKey", "Enabled": true, "GenerateDistinctId": true } }
- 添加Usage Plan资源
同样在Resources节点下新增Usage Plan,关联到自动生成的Serverless Rest API:
"MyUsagePlan": { "Type": "AWS::ApiGateway::UsagePlan", "Properties": { "Name": "MyAppUsagePlan", "ApiStages": [ { "ApiId": { "Ref": "ServerlessRestApi" }, "Stage": "Prod" } ], "Quota": { "Limit": 1000, "Period": "MONTH" }, "Throttle": { "BurstLimit": 100, "RateLimit": 50 } } }
- 关联API Key到Usage Plan
添加Usage Plan Key资源,把上面创建的API Key和Usage Plan关联起来:
"MyUsagePlanKey": { "Type": "AWS::ApiGateway::UsagePlanKey", "Properties": { "KeyId": { "Ref": "MyApiKey" }, "KeyType": "API_KEY", "UsagePlanId": { "Ref": "MyUsagePlan" } } }
- 修改Lambda的API Event配置,开启API Key验证
找到MyAppFunctionsGetGenerated下的Events.RootGet.Properties,添加ApiKeyRequired: true:
"Events": { "RootGet": { "Type": "Api", "Properties": { "Path": "/", "Method": "GET", "ApiKeyRequired": true } } }
- 注意Lambda Annotations的同步机制
因为Metadata.SyncedEvents里包含了RootGet,Annotations工具可能会覆盖部分Event配置。如果出现配置被重置的情况,需要确保ApiKeyRequired的配置是在生成后的template中保留,或者可以考虑调整Annotations的代码属性(比如在C#的Lambda函数上添加对应的属性,不过目前Annotations v1.0.0可能需要手动维护template中的这部分配置)。
完整配置示例
修改后的serverless.template如下:
{ "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", "Description": "An AWS Serverless Application. This template is partially managed by Amazon.Lambda.Annotations (v1.0.0.0).", "Resources": { "MyAppFunctionsGetGenerated": { "Type": "AWS::Serverless::Function", "Metadata": { "Tool": "Amazon.Lambda.Annotations", "SyncedEvents": [ "RootGet" ] }, "Properties": { "Runtime": "dotnet6", "CodeUri": ".", "MemorySize": 256, "Timeout": 30, "Policies": [ "AWSLambdaBasicExecutionRole" ], "PackageType": "Zip", "Handler": "MyApp::MyApp.Functions_Get_Generated::Get", "Events": { "RootGet": { "Type": "Api", "Properties": { "Path": "/", "Method": "GET", "ApiKeyRequired": true } } } } }, "MyApiKey": { "Type": "AWS::ApiGateway::ApiKey", "Properties": { "Name": "MyAppApiKey", "Enabled": true, "GenerateDistinctId": true } }, "MyUsagePlan": { "Type": "AWS::ApiGateway::UsagePlan", "Properties": { "Name": "MyAppUsagePlan", "ApiStages": [ { "ApiId": { "Ref": "ServerlessRestApi" }, "Stage": "Prod" } ], "Quota": { "Limit": 1000, "Period": "MONTH" }, "Throttle": { "BurstLimit": 100, "RateLimit": 50 } } }, "MyUsagePlanKey": { "Type": "AWS::ApiGateway::UsagePlanKey", "Properties": { "KeyId": { "Ref": "MyApiKey" }, "KeyType": "API_KEY", "UsagePlanId": { "Ref": "MyUsagePlan" } } } }, "Outputs": { "ApiURL": { "Description": "API endpoint URL for Prod environment", "Value": { "Fn::Sub": "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/" } }, "ApiKey": { "Description": "Generated API Key", "Value": { "Ref": "MyApiKey" } } } }
部署后,调用API时需要在请求头中携带x-api-key字段,值为生成的API Key(可以从CloudFormation输出或API Gateway控制台获取)。
内容的提问来源于stack exchange,提问作者rabejens
相关产品推荐
相关产品推荐

