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

如何限制AWS S3文件仅允许Cognito用户或访客查看而无法下载

实现S3文件仅可查看播放、禁止下载的完整方案

以下为适配认证/未认证用户访问的全流程实操指导,全程无额外外部依赖:

1 核心架构逻辑

整套方案以CloudFront为统一接入层,S3设为私有源站仅允许CloudFront访问,Cognito做身份校验,Lambda@Edge实现权限控制和下载限制,所有资源访问路径不暴露S3直链。

2 分步实现步骤

2.1 第一步:配置S3存储桶基础规则

  • 关闭存储桶全部公共访问权限,仅通过CloudFront源访问控制(OAC)授予访问权限,禁止任何S3直链访问
  • 存储桶策略参考配置:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::你的存储桶名称/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::你的AWS账号ID:distribution/你的CloudFront分发ID"
                }
            }
        }
    ]
}
  • 不需要开启S3静态网站托管,直接用CloudFront对接S3标准源站即可。

2.2 第二步:配置Cognito身份池(兼容认证+未认证用户)

  • 创建Cognito身份池,勾选启用未认证身份访问,保证未登录访客也能拿到临时访问权限
  • 身份池对应的认证、未认证IAM角色,仅授予AmazonCognitoReadOnly最小权限,不要配置S3直接访问权限
  • 前端侧完成Cognito身份校验后,将拿到的JWT令牌放在Authorization请求头中访问CloudFront资源。

2.3 第三步:配置Lambda@Edge函数(核心控制逻辑)

需要部署2个Lambda@Edge(必须部署在us-east-1区域),分别绑定到CloudFront的不同触发事件:

2.3.1 查看请求触发器(Viewer Request)

用于校验请求身份合法性,拦截非法请求,认证/未认证合法用户全部放行:

// Node.js运行时
exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const authHeader = request.headers.authorization?.[0]?.value;
    
    // 此处补充Cognito JWT校验逻辑,无效令牌按未认证用户处理,恶意请求直接返回403
    // 合法的认证/未认证用户都放行
    callback(null, request);
};

2.3.2 源响应触发器(Origin Response)

用于修改响应头,强制浏览器内联打开资源,禁止触发下载行为:

exports.handler = (event, context, callback) => {
    const response = event.Records[0].cf.response;
    const headers = response.headers;
    
    // 核心配置:强制内联打开,不触发下载弹窗
    headers['content-disposition'] = [{key: 'Content-Disposition', value: 'inline'}];
    // 可选配置:禁止资源缓存,避免链接被分享复用
    headers['cache-control'] = [{key: 'Cache-Control', value: 'no-store, must-revalidate'}];
    
    callback(null, response);
};

注意:Lambda@Edge的执行角色需要添加lambda.amazonaws.com和edgelambda.amazonaws.com两个服务主体到信任关系中。

2.4 第四步:CloudFront分发配置

  • 源站选择目标S3桶,启用OAC关联之前创建的源访问控制
  • 行为配置:默认行为绑定上述两个Lambda@Edge触发器,允许的HTTP方法仅保留GET、HEAD,禁用所有修改类方法
  • 可选配置:启用CloudFront签名URL/签名Cookie,设置资源链接有效期,避免链接被外传滥用。

2.5 CloudFormation栈部署参考

可直接使用以下模板片段组合成完整部署栈,替换对应参数即可:

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  BucketName:
    Type: String
  CognitoIdentityPoolId:
    Type: String
Resources:
  # S3存储桶配置
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
  # CloudFront OAC配置
  CloudFrontOAC:
    Type: AWS::CloudFront::OriginAccessControl
    Properties:
      OriginAccessControlConfig:
        Name: !Sub ${BucketName}-oac
        OriginAccessControlOriginType: s3
        SigningBehavior: always
        SigningProtocol: sigv4
  # 其余CloudFront分发、Lambda@Edge、Cognito角色配置按上述规则补充即可

注意:CloudFormation中部署Lambda@Edge时需要指定AutoPublishAlias: live,再关联CloudFront触发事件。

3 注意事项

  • 没有绝对的防下载方案:只要用户可以正常在线查看/播放资源,就可以通过抓包、浏览器插件等方式提取资源,上述配置仅能阻止普通用户的直接下载行为,对高安全要求的场景需要额外添加DRM加密、动态水印等防护措施
  • Lambda@Edge日志会输出到对应边缘节点所在区域的CloudWatch日志组,排查问题时需要切换到对应区域查看
  • CloudFormation部署Lambda@Edge时如果提示跨区域权限错误,优先检查Lambda执行角色的信任关系配置是否正确。

内容的提问来源于stack exchange,提问作者sameerawsnoob

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 20:36:07