AWS S3调用ListObjects/GetObject遇AccessDenied权限问题求助
权限排查:S3批量读取时的AccessDenied问题
问题描述
指定单个S3文件路径(s3://bucket_name/table_name/file.parquet)时,Python代码可通过pandas正常读取;但通过目录前缀列取所有对象再逐个读取时,触发AccessDenied错误。
原始测试代码:
bucket=bucket_name key=table_name/ objects=s3.list_objects(Bucket=bucket,Prefix=key)['Contents'] print(objects) dfs=[] for obj in objects: file_key=obj['Key'] obj=s3.get_object(Bucket=bucket,Key=file_key) df_single=pd.read_parquet(BytesIO(obj['Body'].read())) dfs.append(df_single) df=pd.concat(dfs, ignore_index=True)
更新后情况
已更新IAM策略,添加桶级资源并附加到Lambda执行角色,策略内容如下:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:ListBucketMultipartUploads", "s3:GetBucketTagging", "s3:ListBucketVersions", "s3:ListBucket", "s3:GetBucketAcl", "s3:BypassGovernanceRetention", "s3:GetBucketPolicy", "s3:ListMultipartUploadParts", "s3:PutObject", "s3:GetObjectAcl", "s3:GetObject", "s3:ObjectOwnerOverrideToBucketOwner", "s3:DescribeJob", "s3:PutObjectVersionAcl", "s3:PutBucketAcl", "s3:PutBucketPolicy", "s3:DeleteAccessPointPolicy", "s3:DeleteObject", "s3:PutAccessPointPolicy", "s3:PutObjectAcl" ], "Resource": [ "arn:aws:s3:::bucket_name", "arn:aws:s3:::bucket_name*/*" ] }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "s3:ListStorageLensConfigurations", "s3:GetAccessPoint", "s3:ListAllMyBuckets", "s3:ListAccessPoints", "s3:ListJobs", "s3:PutStorageLensConfiguration", "s3:CreateJob" ], "Resource": "*" } ] }
运行以下精简代码仍报错:
s3_resource=boto3.resource('s3') bucket = s3_resource.Bucket(bucket_name) for obj in bucket.objects.all(): print(obj.key)
错误信息:
[ERROR] ClientError: An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied
排查方向与解决方案
1. 修正IAM策略中的资源ARN匹配
策略中arn:aws:s3:::bucket_name*/*的通配符使用错误:bucket_name*会匹配名称以bucket_name开头的所有桶(如bucket_name123),而非目标桶下的对象路径。正确的对象资源ARN应为arn:aws:s3:::bucket_name/*。
修正后的核心权限策略示例(精简不必要权限,减少冲突风险):
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowBucketListAndObjectRead", "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetObject" ], "Resource": [ "arn:aws:s3:::bucket_name", // ListBucket操作需要桶级资源 "arn:aws:s3:::bucket_name/*" // GetObject操作需要对象级资源 ] }, { "Sid": "AllowGlobalS3Actions", "Effect": "Allow", "Action": [ "s3:ListAllMyBuckets" ], "Resource": "*" } ] }
2. 检查权限生效与冲突
- 确认Lambda执行角色已正确附加修正后的策略,且策略无语法错误(可通过IAM控制台的策略验证工具检查)。
- 检查是否存在**权限边界(Permission Boundary)**限制该角色的S3访问权限。
- 用IAM Policy Simulator模拟该角色执行
s3:ListBucket(资源选目标桶)和s3:GetObject(资源选目标对象路径)操作,确认权限是否允许。
3. 排查桶级限制
- 检查目标桶的桶策略是否包含Deny语句,阻止了该角色的ListBucket操作。
- 确认S3存储桶未启用Block Public Access中限制内部访问的选项(需结合实际场景判断)。
- 若对象由其他AWS账户上传,检查桶的对象所有权设置:建议启用「Bucket owner enforced」,确保桶所有者拥有对象权限。
4. 代码层面的潜在问题
若权限问题解决后仍有异常,需检查:
- 当桶内对象超过1000个时,
list_objects会分页,需改用list_objects_v2或boto3分页器处理,避免遗漏对象。 - 确认代码中使用的前缀
table_name/正确,无多余空格或拼写错误。
内容的提问来源于stack exchange,提问作者Dozel
相关产品推荐
相关产品推荐

