gpt4 book ai didi

amazon-web-services - AWS Cloudfront(带 WAF)+ API 网关 : how to force access through Cloudfront?

转载 作者:行者123 更新时间:2023-12-03 23:53:05 25 4
gpt4 key购买 nike

我想将 WAF 放在 API 网关前面,并使用 (little) info我发现这只能通过在 APIG 前面手动放置一个启用了 WAF 的额外 Cloudfront 发行版来实现。有点遗憾,特别是因为 APIG 现在原生支持自定义域,但它应该可以工作。

现在为了使解决方案安全而不仅仅是晦涩难懂,我想强制 API 只能通过 Cloudfront 发行版访问。
这样做的最佳选择是什么?

  • 我希望能够使用与 S3 类似的“原始访问身份”,但不知道该怎么做。
  • 如果我可以将 IAM 用户(或角色?)分配给 Cloudfront 发行版,我可以使用 APIG IAM 功能,但我不知道如何做到这一点。
  • 我可能需要 APIG 中的 API key ,并将其作为来自 Cloudfront 的 Origin Custom Header 传递。只要我们不想将 API key 用于其他目的,这可能会奏效,所以我对此并不完全满意。
  • 可以使用虚拟 (!) 自定义授权方, token 验证表达式实际上检查作为来自 Cloudfront 的 Origin Custom Header 传递的 secret 。应该可以,它更灵活,但有点脏……还是不行?

  • 有更好的想法吗?或者也许存在“正确的方法”,但我忽略了它?

    最佳答案

    可以使用 Lambda@Edge function 强制通过 CloudFront 进行访问。对于 SigV4签署原始请求,然后在您的 API 网关上启用 IAM 身份验证。此策略可以与 CloudFront 分配 (guide for CloudFront+API Key) 中的 API key 结合使用。

    假设您已将 API Gateway 设置为 CloudFront 分配的源,您首先需要创建一个 Lambda@Edge 函数 (guide for Lambda@Edge setup),然后确保其执行角色可以访问您想要访问的 API Gateway。为简单起见,您可以使用 AmazonAPIGatewayInvokeFullAccess您的 Lambda 执行角色中的托管 IAM 策略,允许它访问您账户中的任何 API 网关。

    然后,如果你继续使用 aws4作为您的签名客户端,您的 Lambda@Edge 代码如下所示:

    const aws4 = require("aws4");

    const signCloudFrontOriginRequest = (request) => {
    const searchString = request.querystring === "" ? "" : `?${request.querystring}`;

    // Utilize a dummy request because the structure of the CloudFront origin request
    // is different than the signing client expects
    const dummyRequest = {
    host: request.origin.custom.domainName,
    method: request.method,
    path: `${request.origin.custom.path}${request.uri}${searchString}`,
    };

    // Include the body in the signature if present
    if (Object.hasOwnProperty.call(request, 'body')) {
    const { data, encoding } = request.body;
    const buffer = Buffer.from(data, encoding);
    const decodedBody = buffer.toString('utf8');

    if (decodedBody !== '') {
    dummyRequest.body = decodedBody;
    dummyRequest.headers = { 'content-type': request.headers['content-type'][0].value };
    }
    }

    // Use the Lambda's execution role credentials
    const credentials = {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    sessionToken: process.env.AWS_SESSION_TOKEN
    };

    aws4.sign(dummyRequest, credentials); // Signs the dummyRequest object

    // Sign a clone of the CloudFront origin request with appropriate headers from the signed dummyRequest
    const signedRequest = JSON.parse(JSON.stringify(request));
    signedRequest.headers.authorization = [ { key: "Authorization", value: dummyRequest.headers.Authorization } ];
    signedRequest.headers["x-amz-date"] = [ { key: "X-Amz-Date", value: dummyRequest.headers["X-Amz-Date"] } ];
    signedRequest.headers["x-amz-security-token"] = [ { key: "X-Amz-Security-Token", value: dummyRequest.headers["X-Amz-Security-Token"] } ];

    return signedRequest;
    };

    const handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const signedRequest = signCloudFrontOriginRequest(request);

    callback(null, signedRequest);
    };

    module.exports.handler = handler;

    请注意,如果您在请求中包含正文,则必须手动配置 Lambda@Edge 函数以通过控制台或 SDK 包含正文或设置 CloudFormation custom resourceCloudFormation does not support enabling this natively yet 开始调用 SDK

    关于amazon-web-services - AWS Cloudfront(带 WAF)+ API 网关 : how to force access through Cloudfront?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43412908/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com