能否通过SAM创建带自定义授权器的API Gateway直连SNS的CloudFormation模板?
答案:完全可以实现!
Absolutely! AWS SAM (Serverless Application Model) fully supports building this exact setup—an API Gateway method secured by a custom authorizer that directly integrates with Amazon SNS. Since SAM is built on top of CloudFormation, it inherits all the capabilities of CloudFormation for these services, while also offering more concise, serverless-focused syntax to simplify your template.
Let me walk you through how to define this with a complete SAM template example:
核心组件解析
- Custom Authorizer: We'll use SAM's
ApiGatewayAuthorizerresource to link a Lambda function that handles authentication (e.g., validating JWT tokens, API keys, etc.). - API Gateway to SNS Integration: We'll configure an API method with an
AWStype integration that directly sends requests to your SNS topic, no intermediate Lambda required (though you could add one if you need additional request processing).
完整SAM模板示例
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: API Gateway with Custom Authorizer direct to SNS Resources: # 1. Custom Authorizer Lambda Function AuthFunction: Type: AWS::Serverless::Function Properties: Runtime: python3.12 Handler: auth.handler CodeUri: ./auth/ # Path to your authorizer code directory Policies: - AWSLambdaBasicExecutionRole # For CloudWatch logging # 2. SNS Topic to receive API requests TargetSNSTopic: Type: AWS::SNS::Topic Properties: DisplayName: API Gateway Direct SNS Topic # 3. API Gateway with Custom Authorizer and SNS Integration MyApi: Type: AWS::Serverless::Api Properties: StageName: prod Auth: # Define the custom authorizer Authorizers: CustomLambdaAuthorizer: FunctionArn: !GetAtt AuthFunction.Arn FunctionInvokeRole: !GetAtt AuthFunctionRole.Arn # SAM auto-creates this role IdentitySource: method.request.header.Authorization # Pull auth token from header AuthorizerPayloadFormatVersion: "2.0" # Use modern payload format # Apply authorizer to all methods (can override per method if needed) DefaultAuthorizer: CustomLambdaAuthorizer DefinitionBody: openapi: '3.0' info: title: !Ref AWS::StackName paths: /publish: post: x-amazon-apigateway-integration: type: aws uri: !Sub arn:aws:apigateway:${AWS::Region}:sns:action/Publish credentials: !GetAtt ApiGatewaySNSRole.Arn # Role for API Gateway to access SNS httpMethod: POST requestParameters: integration.request.querystring.TopicArn: "'${TargetSNSTopic}'" integration.request.querystring.Message: "method.request.body" responses: default: statusCode: 200 responses: '200': description: Message published to SNS # 4. IAM Role for API Gateway to publish to SNS ApiGatewaySNSRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: apigateway.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: APIGatewaySNSPublish PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: sns:Publish Resource: !Ref TargetSNSTopic
关键细节说明
- Authorizer Configuration: The
IdentitySourcespecifies where API Gateway looks for the authentication token (here, theAuthorizationheader). Adjust this to match your auth mechanism (e.g., query string parameter, cookie). - SNS Integration: The
x-amazon-apigateway-integrationblock maps the API request body directly to the SNSMessageparameter, and hardcodes the target topic ARN. The IAM roleApiGatewaySNSRolegrants API Gateway explicit permission to callsns:Publishon your topic. - Authorizer Lambda Logic: Your actual authorizer code (in
./auth/auth.py) should validate the incoming token and return an IAM policy allowing/denying access. A minimal example:def handler(event, context): token = event['headers'].get('authorization', '') # Add your real validation logic here (e.g., verify JWT signature) if token.startswith("Bearer valid-token-123"): return { "principalId": "user_123", "policyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": event['routeArn'] } ] } } else: raise Exception("Unauthorized") # Triggers 401 response from API Gateway
部署步骤
- Save the template as
template.yaml - Create the
./auth/directory and add yourauth.pyhandler file - Run
sam deploy --guidedto deploy the stack (follow the interactive prompts to configure your deployment)
内容的提问来源于stack exchange,提问作者aGO
相关产品推荐
相关产品推荐

