Python AWS Lambda返回尝试从S3存储桶获取对象时被拒绝的权限

Python AWS Lambda返回尝试从S3存储桶获取对象时被拒绝的权限,python,amazon-web-services,amazon-s3,aws-lambda,Python,Amazon Web Services,Amazon S3,Aws Lambda,我确实创建了一个lambda函数,当文件上传到S3存储桶中时,它应该将数据上传到DynamoDB中。然而,当文件上传到bucket中时,我在CloudWatch中得到一个“GetObject操作:权限被拒绝”。 lambda函数附加了一个IAM角色,以及以下策略:AmazonAmbdaFullAccess、AmazonS3FullAccess、AmazonCloudWatchLogsFullAccess、AmazonDynamodFullAccess。它将lambda.amazonaws.com

我确实创建了一个lambda函数,当文件上传到S3存储桶中时,它应该将数据上传到DynamoDB中。然而,当文件上传到bucket中时,我在CloudWatch中得到一个“GetObject操作:权限被拒绝”。 lambda函数附加了一个IAM角色,以及以下策略:AmazonAmbdaFullAccess、AmazonS3FullAccess、AmazonCloudWatchLogsFullAccess、AmazonDynamodFullAccess。它将lambda.amazonaws.com作为受信任的实体。 bucket没有附加任何策略

 import boto3
 import json
 import urllib

 dynamodb = boto3.resource('dynamodb')
 table = dynamodb.Table('wireshark')
 s3 = boto3.client('s3')
 tests3 = boto3.resource(u's3')

 def lambda_handler(event, context):

     source_bucket = event['Records'][0]['s3']['bucket']['name']
     key = urllib.parse.quote_plus(event['Records'][0]['s3']['object']['key'])
    copy_source = {'Bucket':source_bucket , 'Key':key}
    print(event)
    print("Log stream name : ", context.log_stream_name)
    print("Log group name : ", context.log_group_name)
    print("Request Id:", context.aws_request_id)
    print("Mem. limit(MB): ", context.memory_limit_in_mb)

    #just print function
    print("Log stream name : ", context.log_stream_name)
    print("Log group name : ", context.log_group_name)
    print("Request Id:", context.aws_request_id)
    print("Mem. limit(MB): ", context.memory_limit_in_mb)

    try:
        print("Using waiter to waiting for object to persist thru s3 service")
        waiter = s3.get_waiter('object_exists')
        waiter.wait(Bucket=source_bucket, Key=key)
        print("Accessing the receied file and reading the same")
        bucket = tests3.Bucket(u'awslambdas3test2')
        obj = bucket.Object(key=key)
        response = obj.get()
        print("response from file object")
        print(response)
在Cloudwatch中:调用GetObject操作时发生错误(AccessDenied):拒绝访问。 我已经通过了aws的“政策模拟器”。此IAM角色应该能够从任何S3存储桶获取对象。 谢谢你的帮助


代码主要来自。

这里有一个AWS Lambda函数,它将打印文件的内容:

import boto3
import os

def lambda_handler(event, context):

    s3_client = boto3.client('s3')

    # For each record

    for record in event['Records']:

        # Get Bucket and Key
        bucket = record['s3']['bucket']['name']
        key    = record['s3']['object']['key']

        # Print the bucket & key to the logs
        print(bucket, key)

        # Download object
        local_filename = '/tmp/' + key
        s3_client.download_file(bucket, key, local_filename)

        # Print contents to log (just to demonstrate concept)
        for line in open(local_filename):
            print(line)

        # Delete file when done, to clear space for future execution
        os.remove(local_filename)

在一个bucket上创建一个AmazonS3事件来触发这个Lambda函数,它会将文件名和文件内容打印到CloudWatch日志中。这应该是一个很好的测试,可以确定程序是否使用了您的代码或权限。

哪一行生成了错误?您可能需要删除
并尝试
以找到答案。行
bucket=tests3.bucket(u'awslambdas3test2')
硬编码bucket名称。它应该真正使用
source\u bucket
。假设这不是问题所在,您可以尝试在Lambda控制台中使用amazons3put测试事件和实际的bucket&key测试函数。此外,不需要使用服务员,因为调用函数时对象将可用。生成错误的行是response=obj.get。问题是,文件名没有问题,因为我打印了变量“key”,它打印了我想要访问的文件名。我做了一个Amazon S3 Put测试,我的许可被拒绝了。如上所述,lambda函数对S3具有完全访问权限,而bucket没有任何策略,因此我不明白为什么拒绝该权限。bucket所有者可能无法访问放置在Amazon S3 bucket中的对象,特别是如果该对象是从另一个帐户复制并保留相同权限的话。您能否使用aws CLI通过aws s3 cp
访问该文件?是的,我已经能够使用aws CLI将文件从存储桶复制到本地存储。我已尝试使用另一IAM角色创建另一个lambda,但仍不起作用。您提供的lambda函数可以读取该文件。看起来问题确实来自函数,但我不知道问题出在哪里。你确定这不是
bucket=tests3.bucket(u'awslambdas3test2')
中硬编码的bucket名称吗?我想我改变了它,但显然没有,所以它现在可以工作了。“print(response)”行返回“预期的str、bytes或os.PathLike对象,而不是dict”。我尝试使用CSV文件进行测试,但效果良好,我不明白为什么python文件会出现问题。
Object.get()
返回一个结果字典,包括
LastModified
Versionid
。如果需要对象的内容,请使用
object.get()['Body']
。请参阅文档: