You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何限制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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 01:58:10