【问题标题】:access denied in lambda when trying to access file uploaded to s3 bucket尝试访问上传到 s3 存储桶的文件时,lambda 中的访问被拒绝
【发布时间】:2018-05-21 01:14:48
【问题描述】:

继我在my original post 获得的巨大帮助之后

将文件上传到 s3 存储桶,触发 lambda,它会发送一封电子邮件,其中包含有关上传到 s3 存储桶的文件的信息

我之前测试过发送电子邮件,所以我知道这可行,但是当我尝试包含上传的数据时,它会触发错误

Could not fetch object data:  { AccessDenied: Access Denied
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:577:35)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)

我在网上找到了许多与此相关的关于角色等政策的问题。所以我在 s3 事件中添加了 lambda,并为角色添加了 s3 权限,例如。

https://stackoverflow.com/questions/35589641/aws-lambda-function-getting-access-denied-when-getobject-from-s3

不幸的是,这些都没有帮助。但是我注意到了一条评论

Then the best solution is to allow S3FullAccess, see if it works. If it does, then remove one set of access at a time from the policy and find the least privileges required for your Lambda to work. If it does not work even after giving S3FullAccess, then the problem is elsewhere

那么我该如何寻找问题所在呢?

谢谢你

   'use strict';

console.log('Loading function');

var aws = require('aws-sdk');
var ses = new aws.SES({
   region: 'us-west-2'
});
//var fileType = require('file-type');

console.log('Loading function2');

var s3 = new aws.S3({ apiVersion: '2006-03-01', accessKeyId: process.env.ACCESS_KEY, secretAccessKey: process.env.SECRET_KEY, region: process.env.LAMBDA_REGION });

console.log('Loading function3');
//var textt = "";

exports.handler = function(event, context) {
    console.log("Incoming: ", event);

  //  textt = event.Records[0].s3.object.key;
   // var output = querystring.parse(event);

   //var testData = null;

   // Get the object from the event and show its content type
   // const bucket = event.Records[0].s3.bucket.name;
   // const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const params = {
       Bucket: 'bucket',
       Key: 'key',
    };

    s3.getObject(params, function(err, objectData) {
    if (err) {
        console.log('Could not fetch object data: ', err);
    } else {
        console.log('Data was successfully fetched from object');
        var eParams = {
            Destination: {
                ToAddresses: ["fake@fake.com"]
            },
            Message: {
                Body: {
                    Text: {
                        Data: objectData
                       // Data: textt
                    }
                },
                Subject: {
                    Data: "Email Subject!!!"
                }
            },
            Source: "fake@fake.com"
        };

        console.log('===SENDING EMAIL===');

        var email = ses.sendEmail(eParams, function(err, emailResult) {
            if (err) console.log('Error while sending email', err);
            else {
                console.log("===EMAIL SENT===");
                //console.log(objectData);
                console.log("EMAIL CODE END");
                console.log('EMAIL: ', emailResult);
                context.succeed(event);
            }
        });
    }
});

};

更新 我已将 cmets 添加到代码中并检查了日志...它没有超过这一行

var s3 = new aws.S3({ apiVersion: '2006-03-01', accessKeyId: process.env.ACCESS_KEY, secretAccessKey: process.env.SECRET_KEY, region: process.env.LAMBDA_REGION });

这是否与拒绝访问有关?

注意:所有我想要的上传文件的文件名

更新 2

iv 用var s3 = new aws.S3().getObject({ Bucket: this.awsBucketName, Key: 'keyName' }, function(err, data) { if (!err) console.log(data.Body.toString()); }); 替换了导致问题的行

但这是TypeError: s3.getObject is not a function

也试过了...var s3 = new aws.S3();

这又回到了Could not fetch object data: { AccessDenied: Access Denied原来的错误

【问题讨论】:

    标签: javascript node.js amazon-s3 aws-lambda


    【解决方案1】:

    首先,区域应该是 S3 存储桶区域,而不是 lambda 区域。接下来,您需要验证您的凭证以及他们是否有权访问您定义的 S3 存储桶。正如您在其中一条评论中所述,尝试将 S3 完全访问 Amazon 托管策略附加到您的 IAM 用户,该用户与您在 Lambda 中使用的凭证相关联。下一步将使用 aws cli 查看您是否可以访问此存储桶。也许像 -

    aws s3 ls
    

    如上所述,您根本不应该使用凭据。由于 Lambda 和 S3 是亚马逊服务,您应该使用角色。只需给 Lambda 一个角色,使其能够完全访问 S3,不要为此使用 aws IAM 凭证。和

    var s3 = new AWS.S3();
    

    足够了。

    【讨论】:

    • 嘿阿尼凯特。感谢您的回复....所以....所有 s3 存储桶都是“全球”区域,所以我应该更改为 var ses = new aws.SES({ region: 'global' });...... .......接下来我没有意识到我必须向用户添加权限......我只将它们添加到创建存储桶时使用的角色......所以我也添加了用户'awsLambdaFullAccess、AmazonS3 完全访问权限、管理员访问权限和 Amazon SES 完全访问权限'....我已经尝试了所有这些并再次感谢您,但我仍然被拒绝访问
    • 我认为访问存储桶是可行的,因为如果我将捕获文件详细信息的代码留出空间并将图片上传到 s3 存储桶,它会触发 lambda 并发送电子邮件...所以这一切正常。就在我尝试获取上传文件名时,我遇到了 accessDenied
    • 当存储桶的访问实际上失败时,你怎么说它是有效的?当您将某些内容上传到 S3 时,您会得到由事件触发的 lambda 并发送邮件。没有来自 lambda 的 s3 交互对您有用。正如我之前所说,使用角色并完全避免使用凭据。
    • 如果我让 lambda 保持原样,它只会发送一封电子邮件。此 lamdba 连接到 S3 存储桶的触发器....当我将图像上传到存储桶中时,它会触发 lambda 并发送电子邮件....这是有效的...所以这是否意味着可以访问桶在工作吗?只有当我尝试添加代码以获取上传到存储桶的内容时,它才会失败。对不起,但据我所知,我没有使用凭据,我正在使用角色……在 s3 存储桶中,我在访问控制列表中添加了“公共访问”
    • 并在 lambda 中添加了 iam 执行角色,该角色可以访问 awsLambdaFullAccess、Amazons3Fullaccess、administratorAccess、AmazonSesFUllAccess ......再次感谢您的帮助,但您知道我做错了什么跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 2019-02-03
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多