如何限制AWS CloudFront请求仅允许来自特定URL的访问?
如何限制CloudFront仅允许从特定页面访问S3资源
完全可以实现这个需求,核心思路是通过检查HTTP请求的Referer头验证请求来源,结合CloudFront的边缘计算能力拦截不符合条件的请求。以下是两种可行的实现方案:
方案一:使用CloudFront Functions(轻量高效,适合简单逻辑)
CloudFront Functions是CloudFront提供的轻量边缘计算服务,适合处理简单的请求/响应修改,延迟低且成本低。
步骤1:创建CloudFront Function
编写以下JavaScript代码,用于检查请求的Referer头是否匹配指定页面:
function handler(event) { const request = event.request; const headers = request.headers; // 定义允许的来源页面URL const allowedReferer = "https://www.example.com/gated-page"; // 验证Referer头是否存在且匹配 if (!headers.referer || headers.referer.value !== allowedReferer) { // 返回403禁止访问,也可修改为重定向逻辑 return { statusCode: 403, statusDescription: "Forbidden", headers: { "content-type": { value: "text/html" } }, body: { encoding: "text", data: "访问被拒绝,仅允许从https://www.example.com/gated-page页面访问此资源。" } }; } // 符合条件,允许请求继续流向S3 return request; }
步骤2:关联函数到CloudFront分发
将该函数关联到你的CloudFront分发的Viewer Request事件(用户请求到达CloudFront边缘节点时触发),确保在请求进入缓存层前完成验证。
关键注意事项
Referer头存在被篡改的可能,此方案适合普通场景的访问限制,若需要更高安全性,需结合其他验证方式(如Cookie、签名URL)。- 务必确保S3存储桶仅允许CloudFront的Origin Access Identity(OAI)访问,禁止直接公开S3,避免用户绕开CloudFront的限制。
方案二:使用Lambda@Edge(支持复杂逻辑)
如果需要更复杂的验证逻辑(比如同时检查用户登录状态Cookie+Referer),可以使用Lambda@Edge,它支持更灵活的代码逻辑。
示例Lambda代码(Node.js)
exports.handler = async (event) => { const request = event.Records[0].cf.request; const headers = request.headers; const allowedReferer = "https://www.example.com/gated-page"; // 假设登录后会设置名为user_authenticated的Cookie,值为true const requiredAuthCookie = "user_authenticated=true"; // 检查Referer来源 const referer = headers.referer ? headers.referer[0].value : ""; if (!referer.includes(allowedReferer)) { return { status: '403', statusDescription: 'Forbidden', body: '无效的请求来源,访问被拒绝。', headers: { 'content-type': [{ key: 'Content-Type', value: 'text/html' }] } }; } // 检查用户登录状态Cookie const cookies = headers.cookie ? headers.cookie[0].value.split('; ') : []; const isAuthenticated = cookies.some(cookie => cookie === requiredAuthCookie); if (!isAuthenticated) { // 未登录则重定向到登录页面 return { status: '302', statusDescription: 'Found', headers: { location: [{ key: 'Location', value: 'https://www.example.com/login' }] } }; } // 验证通过,允许请求继续 return request; };
部署说明
- Lambda@Edge函数必须在
us-east-1(弗吉尼亚北部)区域创建,之后关联到CloudFront分发的Viewer Request事件。 - 确保Lambda函数拥有足够的权限(需添加CloudFront相关的执行角色权限)。
额外优化建议
- 若允许来自
gated-page的子路径请求,可修改Referer的匹配逻辑为包含判断(如referer.startsWith("https://www.example.com/gated-page"))。 - 对于静态资源,可在CloudFront中配置缓存策略时,将
Referer头加入缓存键,确保不同来源的请求不会共享缓存。
内容的提问来源于stack exchange,提问作者James Hubert
相关产品推荐
相关产品推荐

