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

如何使用联合账户上传文件至带公开策略的S3存储桶

解决联合账户上传文件到S3存储桶的问题

核心问题梳理

  1. 当前S3桶策略仅开放了公共读取权限(s3:GetObject),完全未配置上传相关权限,这是无法上传的直接原因。
  2. 联合账户确实无法获取长期Access Key/Secret Key,必须依赖临时凭证或环境自动授权的方式操作。

具体解决方案

方案1:调整S3桶策略(允许公开上传,注意安全风险)

若你的业务场景允许公开上传文件,可修改桶策略添加s3:PutObject权限,修改后的策略如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowPublicRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<my-bucket-name>/*"
        },
        {
            "Sid": "AllowPublicUpload",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<my-bucket-name>/*"
        }
    ]
}

注意:公开上传会允许任何人往桶内传文件,可能带来存储成本浪费、垃圾文件堆积甚至安全风险,非必要不建议采用此方案。

方案2:给联合账户关联的IAM角色添加S3上传权限(推荐)

联合账户通常通过IAM角色授权,只需给当前使用的角色添加上传权限即可:

  1. 找到你联合账户对应的IAM角色(即登录后实际使用的角色)
  2. 给该角色附加如下权限策略:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::<my-bucket-name>/*"
        }
    ]
}
  1. 修改boto3代码,删除手动指定密钥的部分,boto3会自动从环境中获取联合账户的临时凭证:
import boto3

# 无需手动创建带密钥的session,直接获取S3资源
s3 = boto3.resource('s3')

txt_data = b'This is the content of the file uploaded from python boto3 asdfasdf'

object = s3.Object('<bucket_name>', 'file_uploaded_by_boto3.txt')

result = object.put(Body=txt_data)

此方式安全性最高,仅你的联合账户角色拥有上传权限,不会公开开放桶的写入能力。

方案3:使用预签名URL上传

若无法修改IAM角色或桶策略,可让拥有该桶权限的用户生成预签名URL,你通过此URL直接上传:

  1. 有权限的用户运行以下代码生成预签名URL:
import boto3

s3 = boto3.client('s3')
url = s3.generate_presigned_url(
    'put_object',
    Params={'Bucket': '<my-bucket-name>', 'Key': 'file_uploaded_by_boto3.txt'},
    ExpiresIn=3600  # URL有效期1小时,可按需调整
)
  1. 你拿到URL后,用requests库直接上传:
import requests

txt_data = b'This is the content of the file uploaded from python boto3 asdfasdf'
response = requests.put(url, data=txt_data)
print(response.status_code)  # 返回200即为上传成功

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:48:17