为CloudFront实施Lambda @ Edge身份验证

时间:2017-08-21 15:03:01

标签: amazon-web-services lambda aws-lambda

我希望将Lambda @ Edge添加到我们的某项服务中。目标是对特定值的url进行正则表达式,并将其与标头值进行比较以确保授权。如果该值存在则将其进行比较,如果被拒绝则应立即向用户返回403。如果比较的值匹配或者url不包含特定值,则请求继续作为授权请求。

最初我认为这会发生在"查看器请求"事件。关于SO的一些帖子和评论表明"来源请求"这个检查更理想。但是现在我一直试图在我们的一个CF端点上的文档中使用示例,但是我没有看到预期的结果。代码如下:

'use strict';
exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    request.headers["edge-test"] = [{
        key:   'edge-test', 
        value: Date.now().toString()
    }];

    console.log(require('util').inspect(event, { depth: null }));

    callback(null, request);
};

我希望云观察中应该有一个记录的值,并且请求中有一个新的标头值,但我没有看到任何日志,也没有看到请求进入时的标头值。

有人可以解释为什么事情似乎没有按照我认为应该做出的反应来执行?我对预期输出错误的理解是什么?是否存在我可能丢失的配置(触发器上的我的分发ID设置为我们想要的实例,并且行为设置为' *')?任何帮助表示赞赏:)

1 个答案:

答案 0 :(得分:2)

首先,注意几点;

CloudFront是(除其他外)网络缓存。

Web缓存的目的是直接向浏览器提供内容,而不是将请求发送到源服务器。

但是,缓存必须正确执行的最重要的事情之一是返回错误的内容。缓存可以返回错误内容的方法之一是没有意识到某些请求标头可能导致orogin服务器改变它为给定URI返回的响应。

CloudFront没有完全了解这一点的方法,因此默认情况下,它的解决方案是在将请求转发到源之前从请求中删除几乎所有的标头。然后它将收到的响应缓存到完全它发送到源的请求,并且只将该缓存的响应用于将来的相同的请求。

在查看器请求触发器中注入新标头将导致该标头在通过匹配的缓存行为后被丢弃,除非缓存行为专门配置为将该标头列入白名单以转发到源。如果浏览器本身已经注入了标题,则会出现这种情况。

因此,将此标头传递到原点的解决方案是在缓存行为设置中将其列入白名单。

如果你尝试使用相同的代码作为Origin Request触发器而没有标题列入白名单,CloudFront实际上会抛出502 Bad Gateway错误,因为你试图注入一个CloudFront已经知道你没有列入白名单的标题在匹配的缓存行为中。 (在查看器请求中,尚未发生缓存行为匹配,因此CloudFront无法判断您是否正在使用最终无法正常工作的标头。在Origin Request中,它知道。)流程是查看者请求&gt ;缓存行为>缓存检查> (如果缓存未命中)Origin Request>发送到Origin Server。将标题列入白名单也可以解决此问题。

您希望原点查看的任何标题,无论是来自浏览器还是请求触发器,都必须列入白名单。

请注意some headers are inaccessible or immutable,特别是那些可用于为欺诈目的选择CloudFront(例如请求伪造和欺骗)以及那些根本没有意义进行修改的内容。