如何在AWS CloudFormation中为API Gateway V2路由关联授权器?
API Gateway V2 多环境独立Lambda授权器的CloudFormation配置方案
问题描述
我正在使用API Gateway V2和CloudFormation,配置了prod与stg两个环境,希望为这两个环境分别使用独立的Lambda授权器。在AWS控制台的「路由」板块中,只需点击「关联授权」按钮即可完成操作,但我不清楚如何在CloudFormation中实现该配置。此外我在apigatewayv2的CLI文档中也未找到相关操作选项。
现有CloudFormation模板片段:
Authorizer: Type: 'AWS::ApiGatewayV2::Authorizer' Properties: ApiId: !Ref ApiGateway AuthorizerPayloadFormatVersion: 2.0 AuthorizerResultTtlInSeconds: 5 AuthorizerType: REQUEST AuthorizerUri: !Join - '' - - 'arn:' - !Ref 'AWS::Partition' - ':apigateway:' - !Ref 'AWS::Region' - ':lambda:path/2015-03-31/functions/' - 'arn:aws:lambda:' - !Ref 'AWS::Region' - ':' - !Ref 'AWS::AccountId' - :function:${stageVariables.AuthorizerFunctionName} - /invocations EnableSimpleResponses: true IdentitySource: - '$request.header.Authorization' Name: !Sub ${ProjectName}-gateway-authorizer MyRoute: Type: AWS::ApiGatewayV2::Route Properties: ApiId: !Ref ApiGateway AuthorizationType: CUSTOM AuthorizerId: !Ref Authorizer RouteKey: 'POST /posts/all' Target: !Join - / - - integrations - !Ref PostsLambdaIntegrationGet
授权器Lambda代码:
import json # import jwt def lambda_handler(event, context): print('*********** The event is: ***************') print(event) print('headers is:') print(event['headers']) print('headers Authorization is:') # !!!!! DOWNCASE by postman or api !!!!! "A" -> "a" print(event['headers']['authorization']) if event['headers']['authorization'] == 'abc123': response = { "isAuthorized": True, "context": { "anyotherparam": "values" } } else: response = { "isAuthorized": False, "context": { "anyotherparam": "values" } } print('response is:') print(response) return response
解决方案
核心思路
API Gateway V2的授权器是全局绑定到API实例的,无法通过stage变量动态切换。要实现多环境独立授权,需为每个环境单独创建AWS::ApiGatewayV2::Authorizer资源,并在对应环境的路由配置中关联该环境的授权器ID。
修改后的CloudFormation配置示例
1. 分环境创建独立授权器
# 生产环境授权器 ProdAuthorizer: Type: 'AWS::ApiGatewayV2::Authorizer' Properties: ApiId: !Ref ApiGateway AuthorizerPayloadFormatVersion: 2.0 AuthorizerResultTtlInSeconds: 5 AuthorizerType: REQUEST AuthorizerUri: !Join - '' - - 'arn:' - !Ref 'AWS::Partition' - ':apigateway:' - !Ref 'AWS::Region' - ':lambda:path/2015-03-31/functions/' - !GetAtt ProdAuthorizerLambda.Arn # 直接绑定生产环境Lambda ARN - /invocations EnableSimpleResponses: true IdentitySource: - '$request.header.Authorization' Name: !Sub ${ProjectName}-gateway-authorizer-prod # 测试环境授权器 StgAuthorizer: Type: 'AWS::ApiGatewayV2::Authorizer' Properties: ApiId: !Ref ApiGateway AuthorizerPayloadFormatVersion: 2.0 AuthorizerResultTtlInSeconds: 5 AuthorizerType: REQUEST AuthorizerUri: !Join - '' - - 'arn:' - !Ref 'AWS::Partition' - ':apigateway:' - !Ref 'AWS::Region' - ':lambda:path/2015-03-31/functions/' - !GetAtt StgAuthorizerLambda.Arn # 直接绑定测试环境Lambda ARN - /invocations EnableSimpleResponses: true IdentitySource: - '$request.header.Authorization' Name: !Sub ${ProjectName}-gateway-authorizer-stg
2. 分环境路由关联对应授权器
通过路由前缀区分环境,为每个环境的路由绑定专属授权器:
# 生产环境路由 ProdMyRoute: Type: AWS::ApiGatewayV2::Route Properties: ApiId: !Ref ApiGateway AuthorizationType: CUSTOM AuthorizerId: !Ref ProdAuthorizer # 关联生产环境授权器 RouteKey: 'POST /prod/posts/all' Target: !Join - / - - integrations - !Ref PostsLambdaIntegrationProdGet # 测试环境路由 StgMyRoute: Type: AWS::ApiGatewayV2::Route Properties: ApiId: !Ref ApiGateway AuthorizationType: CUSTOM AuthorizerId: !Ref StgAuthorizer # 关联测试环境授权器 RouteKey: 'POST /stg/posts/all' Target: !Join - / - - integrations - !Ref PostsLambdaIntegrationStgGet
3. 配置Lambda调用权限
确保每个授权器Lambda允许API Gateway调用:
# 生产环境Lambda权限 ProdAuthorizerLambdaPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !Ref ProdAuthorizerLambda Principal: apigateway.amazonaws.com SourceArn: !Sub 'arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGateway}/*/*/*' # 测试环境Lambda权限 StgAuthorizerLambdaPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !Ref StgAuthorizerLambda Principal: apigateway.amazonaws.com SourceArn: !Sub 'arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGateway}/*/*/*'
关键注意事项
- 禁止使用stage变量动态引用授权器:API Gateway V2不支持通过stage变量切换授权器,必须为每个环境创建独立资源。
- 环境隔离:可以为prod和stg环境部署不同逻辑的Lambda授权器(比如prod用JWT验证,stg用简单密钥),实现环境间的权限逻辑隔离。
- 头部处理:API Gateway会将请求头转为小写,代码中
event['headers']['authorization']的写法是正确的。
内容的提问来源于stack exchange,提问作者robertbeb
相关产品推荐
相关产品推荐

