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

SpringBoot应用上传至私有S3存储桶 仅允许指定Web应用访问方案问询

问题核心现状

你当前的配置存在三个核心问题,导致任何人都可以直接访问S3对象URL:

  1. 存储桶策略直接允许所有主体调用s3:GetObject接口,等于完全开放公开读权限
  2. CORS策略中GET请求允许了所有来源,没有限制跨站访问范围
  3. 未开启公共访问拦截,存在配置错误导致资源泄露的风险

可选实现方案

方案1:限制请求Referer(快速实现,适合低安全要求场景)

该方案可以直接拦截普通用户在浏览器直接输入URL的访问请求,配置简单:

  1. 替换你的存储桶策略为以下内容,将https://www.your-web-app.com替换为你实际的Web应用域名:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowGetFromSpecificReferer",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::nameofthebucket/*",
            "Condition": {
                "StringLike": {
                    "aws:Referer": [
                        "https://www.your-web-app.com/*",
                        "https://your-web-app.com/*"
                    ]
                }
            }
        }
    ]
}
  1. 修改CORS策略,将GET请求的允许来源改为仅你的Web应用域名:
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "http://www.example1.com"
        ],
        "ExposeHeaders": []
    },
    {
        "AllowedHeaders": [],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "https://www.your-web-app.com",
            "https://your-web-app.com"
        ],
        "ExposeHeaders": []
    }
]

注意:该方案存在局限性,Referer请求头可以被人为伪造,无法防御刻意构造的非法访问请求。


方案2:签名URL/签名Cookie(生产环境推荐,安全性最高)

该方案从权限根源限制访问,只有你的Web应用可以生成合法的访问链接,原始S3对象URL直接访问会被拒绝:

  1. 删除原有允许公开读的存储桶策略,开启S3桶的「Block public access」全部四个拦截选项
  2. 给你的Web应用对应的IAM身份(服务器角色、应用服务账号等)授予s3:GetObject权限
  3. 所有S3资源的访问链接由Web应用后端生成,调用AWS SDK生成带过期时间的签名URL,过期时间可根据业务需求设置(通常为几分钟到几小时),Python示例代码如下:
import boto3
from botocore.config import Config

s3 = boto3.client('s3', config=Config(signature_version='s3v4'))
signed_url = s3.generate_presigned_url(
    'get_object',
    Params={'Bucket': 'nameofthebucket', 'Key': 'your-object-key'},
    ExpiresIn=3600 # 签名有效期1小时,单位为秒
)
  1. 前端直接使用后端返回的签名URL访问资源即可,用户即使拿到原始S3对象URL也无法访问。

方案3:限制固定出口IP(适合Web应用有固定公网IP的场景)

如果你的Web应用部署在有固定公网出口IP的服务器上,可以直接在存储桶策略中限制仅该IP可以访问,策略示例如下,替换1.2.3.4/32为你实际的出口IP段:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowGetFromSpecificIP",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::nameofthebucket/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "1.2.3.4/32"
                }
            }
        }
    ]
}

注意事项

  • 所有存储桶权限配置修改后可以先测试普通访问是否被拦截、应用内访问是否正常,避免影响业务
  • 签名URL的生成逻辑必须放在后端实现,禁止在前端代码中硬编码S3访问密钥
  • 有CDN加速需求的场景可以搭配CloudFront使用,通过CloudFront OAC访问S3,完全隐藏S3源站入口,进一步提升安全性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:54:08