如何使用CDK为Amazon Cognito用户池添加WAF防护
使用AWS CDK为Amazon Cognito用户池附加WAF的实现方案
目前AWS CDK的Cognito官方文档确实没有提供直接为用户池附加WAF的示例,因为Cognito用户池本身不支持直接关联WAF。通常需要通过API Gateway代理Cognito操作或者CloudFront搭配Cognito托管UI的方式来实现WAF防护,以下是两种可行的方案:
方案一:通过API Gateway代理Cognito操作并绑定WAF
这种方式适合自定义Cognito交互逻辑的场景,通过API Gateway作为中间层承接请求,再转发到Cognito,同时为API Gateway配置WAF实现防护。
代码示例(TypeScript)
import * as cdk from 'aws-cdk-lib'; import * as cognito from 'aws-cdk-lib/aws-cognito'; import * as apigateway from 'aws-cdk-lib/aws-apigateway'; import * as wafv2 from 'aws-cdk-lib/aws-wafv2'; import * as lambda from 'aws-cdk-lib/aws-lambda'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'CognitoWafProxyStack'); // 1. 创建Cognito用户池及客户端 const userPool = new cognito.UserPool(stack, 'UserPool', { selfSignUpEnabled: true, signInAliases: { email: true }, }); const userPoolClient = userPool.addClient('UserPoolClient'); // 2. 创建WAF Web ACL(API Gateway需使用REGIONAL范围) const webAcl = new wafv2.CfnWebACL(stack, 'ApiGatewayWebAcl', { defaultAction: { allow: {} }, scope: 'REGIONAL', visibilityConfig: { cloudWatchMetricsEnabled: true, metricName: 'ApiGatewayWebAclMetrics', sampledRequestsEnabled: true, }, rules: [ { name: 'BlockSQLInjection', priority: 1, statement: { sqlInjectionMatchStatement: { fieldToMatch: { body: {} } }, }, action: { block: {} }, visibilityConfig: { cloudWatchMetricsEnabled: true, metricName: 'BlockSQLInjectionMetrics', sampledRequestsEnabled: true, }, }, ], }); // 3. 创建API Gateway并关联WAF const api = new apigateway.RestApi(stack, 'CognitoProxyApi'); new wafv2.CfnWebACLAssociation(stack, 'ApiGatewayWafAssociation', { resourceArn: api.deploymentStage.stageArn, webAclArn: webAcl.attrArn, }); // 4. 添加登录接口(Lambda集成转发请求到Cognito) const loginLambda = new lambda.Function(stack, 'LoginLambda', { runtime: lambda.Runtime.NODEJS_18_X, handler: 'index.handler', code: lambda.Code.fromInline(` const AWS = require('aws-sdk'); const cognito = new AWS.CognitoIdentityServiceProvider(); exports.handler = async (event) => { const { username, password } = JSON.parse(event.body); try { const result = await cognito.initiateAuth({ AuthFlow: 'USER_PASSWORD_AUTH', ClientId: '${userPoolClient.userPoolClientId}', AuthParameters: { USERNAME: username, PASSWORD: password } }).promise(); return { statusCode: 200, body: JSON.stringify(result) }; } catch (err) { return { statusCode: 400, body: JSON.stringify(err) }; } }; `), }); api.root.addResource('login').addMethod('POST', new apigateway.LambdaIntegration(loginLambda));
方案二:为Cognito托管UI配置CloudFront并绑定WAF
如果使用Cognito提供的托管UI进行用户认证,可以通过CloudFront托管托管UI的访问入口,同时为CloudFront配置WAF防护。
代码示例(TypeScript)
import * as cdk from 'aws-cdk-lib'; import * as cognito from 'aws-cdk-lib/aws-cognito'; import * as cloudfront from 'aws-cdk-lib/aws-cloudfront'; import * as wafv2 from 'aws-cdk-lib/aws-wafv2'; import * as origins from 'aws-cdk-lib/aws-cloudfront-origins'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'CognitoCloudFrontWafStack'); // 1. 创建Cognito用户池及托管UI客户端 const userPool = new cognito.UserPool(stack, 'UserPool', { selfSignUpEnabled: true, signInAliases: { email: true }, }); const userPoolClient = userPool.addClient('HostedUIClient', { oAuth: { callbackUrls: ['https://your-domain.com/callback'], logoutUrls: ['https://your-domain.com/logout'], }, }); // 2. 创建Cognito自定义域名 const cognitoDomain = userPool.addDomain('CognitoDomain', { cognitoDomain: { domainPrefix: 'your-unique-prefix' }, }); const cognitoOriginDomain = cognitoDomain.baseUrl().replace('https://', ''); // 3. 创建WAF Web ACL(CloudFront需使用CLOUDFRONT范围) const webAcl = new wafv2.CfnWebACL(stack, 'CloudFrontWebAcl', { defaultAction: { allow: {} }, scope: 'CLOUDFRONT', visibilityConfig: { cloudWatchMetricsEnabled: true, metricName: 'CloudFrontWebAclMetrics', sampledRequestsEnabled: true, }, rules: [ { name: 'BlockXSS', priority: 1, statement: { xssMatchStatement: { fieldToMatch: { body: {} } }, }, action: { block: {} }, visibilityConfig: { cloudWatchMetricsEnabled: true, metricName: 'BlockXSSMetrics', sampledRequestsEnabled: true, }, }, ], }); // 4. 创建CloudFront分发并关联WAF new cloudfront.Distribution(stack, 'CognitoHostedUIDistribution', { defaultBehavior: { origin: new origins.HttpOrigin(cognitoOriginDomain), viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, }, webAclId: webAcl.attrArn, });
注意事项
- Cognito用户池本身无直接绑定WAF的入口,必须通过中间层(API Gateway/CloudFront)实现防护
- WAF的
scope需与关联资源匹配:API Gateway用REGIONAL,CloudFront用CLOUDFRONT - 确保中间层的请求转发逻辑正确,避免出现权限或路径匹配错误
内容的提问来源于stack exchange,提问作者kokito
相关产品推荐
相关产品推荐

