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

本地Python代码访问S3遇权限拒绝,AWS控制台Lambda运行正常问题排查

AWS Lambda本地运行S3访问权限问题解答

问题描述

我是Python和AWS Lambda的新手,已在AWS控制台创建了一段Lambda函数代码(如下),该函数可列出S3桶demo-bucket内的文件,通过控制台测试完全正常。但在本地运行类似Python代码时,调用ListObjects操作出现botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied错误。本地代码会先获取指定Lambda函数的配置,再访问S3桶demo-bucket,请问为何本地运行会出错?我哪里操作有误?

控制台Lambda函数代码

import boto3
import json


def lambda_handler(event, context):

    s3 = boto3.resource('s3')
    bucket = s3.Bucket('demo-bucket')

    for file in bucket.objects.all():
        print(file.key, file.last_modified)
     
    return {
        "statusCode": 200,
        "body": json.dumps('Hello from Lambda!')
        }

本地Python代码

import boto3
import json
import os


def lambda_handler():

    lambda_client = boto3.client('lambda')
    role_response = (lambda_client.get_function_configuration(
        FunctionName = os.environ['LAMBDA_FUNCTION'])
    )

    print(role_response['Role'])
    
    s3 = boto3.resource('s3')
    bucket = s3.Bucket('demo-bucket')

    for file in bucket.objects.all():
        print(file.key, file.last_modified)
     
    return {
        "statusCode": 200,
        "body": json.dumps('Hello from Lambda!')
        }

lambda_handler()

注:FunctionName = os.environ['LAMBDA_FUNCTION']指定的是控制台中测试正常的Lambda函数。

原因及解决方法

核心原因

  • 权限上下文不一致:控制台的Lambda函数运行时,使用的是你为该Lambda配置的IAM角色权限,这个角色已经被授予访问demo-bucket的权限。而本地运行Python代码时,boto3会读取你本地环境的AWS凭证(比如~/.aws/credentials文件中的密钥、系统环境变量里的AWS密钥对,或者AWS CLI默认配置的用户),这些本地凭证没有被赋予访问demo-bucket的ListObjects权限,因此触发AccessDenied错误。
  • 获取角色≠使用角色权限:你本地代码中只是调用get_function_configuration拿到了Lambda角色的ARN,但这仅仅是获取角色的元数据,并没有让本地代码切换到该角色下运行。boto3不会自动使用这个角色的权限,仍然沿用本地默认凭证的权限。

解决方法

方法一:给本地凭证添加S3访问权限

在AWS IAM控制台找到你本地使用的AWS用户(即本地凭证对应的用户),创建并附加一条权限策略,允许该用户对demo-bucket执行s3:ListBucket操作。示例策略如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::demo-bucket"
        }
    ]
}

方法二:临时切换到Lambda的IAM角色运行

使用AWS STS的assume_roleAPI,让本地代码临时获取Lambda角色的临时凭证,再用这些凭证初始化S3客户端。修改后的本地代码示例如下:

import boto3
import json
import os

def lambda_handler():
    lambda_client = boto3.client('lambda')
    role_response = lambda_client.get_function_configuration(
        FunctionName = os.environ['LAMBDA_FUNCTION']
    )
    role_arn = role_response['Role']
    
    # 获取Lambda角色的临时凭证
    sts_client = boto3.client('sts')
    assumed_role = sts_client.assume_role(
        RoleArn=role_arn,
        RoleSessionName='LocalLambdaSession'
    )
    
    # 使用临时凭证初始化S3资源
    s3 = boto3.resource(
        's3',
        aws_access_key_id=assumed_role['Credentials']['AccessKeyId'],
        aws_secret_access_key=assumed_role['Credentials']['SecretAccessKey'],
        aws_session_token=assumed_role['Credentials']['SessionToken']
    )
    
    bucket = s3.Bucket('demo-bucket')
    for file in bucket.objects.all():
        print(file.key, file.last_modified)
     
    return {
        "statusCode": 200,
        "body": json.dumps('Hello from Lambda!')
        }

lambda_handler()

注意:使用此方法需要满足两个条件:

  1. 本地的AWS凭证拥有sts:AssumeRole权限;
  2. Lambda的IAM角色信任策略中,添加允许本地用户/角色进行角色切换的规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 23:50:29