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

使用PHP SDK可访问单个AWS S3对象,列取对象时遭403拒绝

问题:AWS S3可生成单个对象预签名URL,但无法列取对象列表返回403错误

我拥有某AWS S3存储桶的访问权限,可通过以下PHP代码拉取单个文件并生成预签名URL:

public function show_s3_object($file_key) {
    $s3_bucket = getenv('S3_BUCKET');
    $s3_key = getenv('S3_KEY');
    $s3_secret = getenv('S3_SECRET');

    if(!empty($file_key))
    {
        $credentials = new Credentials($s3_key, $s3_secret);
        $bucket = $s3_bucket;
        $s3Client = new S3Client([
            'version'     => 'latest',
            'region'      => 'us-east-1', 
            'credentials' => $credentials
        ]);

        $cmd = $s3Client->getCommand('GetObject', [
            'Bucket' => $bucket,
            'Key'    => $file_key
        ]);

        $request = $s3Client->createPresignedRequest($cmd, '+10 minutes');

        $signedUrl = (string) $request->getUri();

        return $signedUrl;
    }
    
}

但尝试列取该存储桶内的对象时,始终返回403 Forbidden错误。我已尝试多种列取方式,例如:

$cmd = $s3Client->getCommand('ListObjects', [
    'Bucket' => $bucket
]);

或

$cmd = $s3client->listObjects([
    'Bucket' => $bucket
]);

当前使用以下代码仍触发403错误:

public function list_objects() {
    //correct code semmingly but getting 403 forbidden

    $s3_bucket = getenv('S3_BUCKET');
    $s3_key = getenv('S3_KEY');
    $s3_secret = getenv('S3_SECRET');
    $credentials = new Credentials($s3_key, $s3_secret);
    $s3Client = new S3Client([
        'version'     => 'latest',
        'region'      => 'us-east-1',
        'credentials' => $credentials
    ]);
    try {
        $objects = $s3Client->getIterator('ListObjects', array(
            'Bucket' => $s3_bucket
        ));
      
       echo "Keys retrieved!\n";
       foreach ($objects as $object) {
           echo $object['Key'] . "\n";
       }
      } catch (S3Exception $e) {
        echo $e->getMessage() . "\n";
       }

}

原因与解决方案

核心原因是你使用的IAM凭证仅拥有单个对象的访问权限(s3:GetObject),但缺少存储桶级别的列取对象权限(s3:ListBucket)。

具体分析:

  • 生成预签名URL或直接获取单个对象,只需要目标对象的s3:GetObject权限,该权限可通过IAM策略授予单个对象路径,示例:
    {
        "Effect": "Allow",
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
    
  • 而列取存储桶内对象(ListObjects/listObjects/getIterator('ListObjects'))需要存储桶级别的s3:ListBucket权限,对应的IAM策略需指定存储桶本身作为资源:
    {
        "Effect": "Allow",
        "Action": "s3:ListBucket",
        "Resource": "arn:aws:s3:::your-bucket-name"
    }
    

解决步骤:

  1. 登录AWS控制台,进入IAM服务,找到当前凭证对应的IAM用户或角色。
  2. 编辑该实体的权限策略,添加包含s3:ListBucket权限的语句,注意资源要指向存储桶ARN(不带/*后缀)。
  3. 保存策略后重新测试列取对象代码,403错误即可解决。

权限缩小优化(可选):

如果仅需列取特定前缀下的对象,可在s3:ListBucket策略中添加条件限制,进一步缩小权限范围:

{
    "Effect": "Allow",
    "Action": "s3:ListBucket",
    "Resource": "arn:aws:s3:::your-bucket-name",
    "Condition": {
        "StringLike": {
            "s3:prefix": "your-target-prefix/*"
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:43:20