如何使用带有AWS临时凭证的java从s3 bucket下载文件

如何使用带有AWS临时凭证的java从s3 bucket下载文件,java,amazon-web-services,amazon-s3,aws-lambda,Java,Amazon Web Services,Amazon S3,Aws Lambda,我有这段代码从s3 bucket下载一个文件到lambda服务器的tmp空间 String url = "https://slack-automation.s3.amazonaws.com/slack.xlsx"; URL link = new URL(url); /* //AmazonS3 s3Client = new AmazonS3Client(new ProfileCredentialsProvider()); AmazonS3 s3Client = AmazonS3Clien

我有这段代码从s3 bucket下载一个文件到lambda服务器的tmp空间

String url = "https://slack-automation.s3.amazonaws.com/slack.xlsx";

URL link = new URL(url);

/* //AmazonS3 s3Client = new AmazonS3Client(new ProfileCredentialsProvider());
   AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build() ;
   S3Object object = s3Client.getObject(new GetObjectRequest(bucketName, key));
   InputStream objectData = object.getObjectContent();
   // Process the objectData stream.
   objectData.close();
 */

// Code to download
InputStream in = new BufferedInputStream(link.openStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n = 0;

while (-1 != (n = in.read(buf))) {
    out.write(buf, 0, n);
}

out.close();
in.close();
byte[] response = out.toByteArray();

FileOutputStream fos = new FileOutputStream("/tmp/" + fileName);
fos.write(response);
fos.close();
file = new File("/tmp/" + fileName);

//file = new File(filePath);
inputStream = new FileInputStream(file);
workBook = new XSSFWorkbook(inputStream);
workBookSheet = workBook.getSheet(workBook.getSheetName(0));
rowCount = workBookSheet.getPhysicalNumberOfRows();
formatter = new DataFormatter();
但问题是要访问此文件,必须获得公共许可

如何通过获取此处提供的临时凭据将此文件下载到lambda server tmp空间:

我无法实现,请有人帮我下载带有临时凭据的文件,而不传递我的accesskey和secretkey,就像上面提到的方法一样

谢谢Akshay Sing,我不知道如何用代码进行评论,我在你回答后尝试的代码在这里

公共无效设置工作簿(字符串文件路径)引发IOException{

    String clientRegion = "eu-central-1";
    String roleARN = "myAwsArnRoleOverHere";
    String roleSessionName = "slackautomation";
    String bucketName = "slack-automation";
    String key = "slack.xlsx";


    String fileName = "slack.xlsx";



    try {

        AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
                                                .withCredentials(new ProfileCredentialsProvider())
                                                .withRegion(clientRegion)
                                                .build();

        AssumeRoleRequest roleRequest = new AssumeRoleRequest()
                                                .withRoleArn(roleARN)
                                                .withRoleSessionName(roleSessionName);
        stsClient.assumeRole(roleRequest);

        // Start a session.
        GetSessionTokenRequest getSessionTokenRequest = new GetSessionTokenRequest();
        // The duration can be set to more than 3600 seconds only if temporary
        // credentials are requested by an IAM user rather than an account owner.
        getSessionTokenRequest.setDurationSeconds(900);
        GetSessionTokenResult sessionTokenResult = stsClient.getSessionToken(getSessionTokenRequest);
        Credentials sessionCredentials = sessionTokenResult.getCredentials();

        // Package the temporary security credentials as a BasicSessionCredentials object 
        // for an Amazon S3 client object to use.
        BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials(
                sessionCredentials.getAccessKeyId(), sessionCredentials.getSecretAccessKey(),
                sessionCredentials.getSessionToken());

        // Provide temporary security credentials so that the Amazon S3 client 
        // can send authenticated requests to Amazon S3. You create the client 
        // using the basicSessionCredentials object.
        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                                .withCredentials(new AWSStaticCredentialsProvider(basicSessionCredentials))
                                .withRegion(clientRegion)
                                .build();

        // Verify that assuming the role worked and the permissions are set correctly
        // by getting a set of object keys from the bucket.
        ObjectListing objects = s3Client.listObjects(bucketName);

        System.out.println("No. of Objects: " + objects.getObjectSummaries().size());
        S3Object fileObject = s3Client.getObject(new GetObjectRequest(bucketName, key));         
        InputStream in = new BufferedInputStream(fileObject.getObjectContent());

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        byte[] buf = new byte[1024];

        int n = 0;

        while (-1 != (n = in.read(buf))) {

            out.write(buf, 0, n);

        }

        out.close();
        in.close();
        byte[] response = out.toByteArray();
        FileOutputStream fos = new FileOutputStream("/tmp/" + fileName);

        fos.write(response);

        fos.close();
        file = new File("/tmp/" + fileName);

        //file = new File(filePath);

        inputStream = new FileInputStream(file);

        workBook = new XSSFWorkbook(inputStream);

        workBookSheet = workBook.getSheet(workBook.getSheetName(0));

        rowCount = workBookSheet.getPhysicalNumberOfRows();

        formatter = new DataFormatter();


    }
    catch(AmazonServiceException e) {
        // The call was transmitted successfully, but Amazon S3 couldn't process 
        // it, so it returned an error response.
        e.printStackTrace();
    }
    catch(SdkClientException e) {
        // Amazon S3 couldn't be contacted for a response, or the client
        // couldn't parse the response from Amazon S3.
        e.printStackTrace();
    }
但它不起作用,它在“stsClient.assumeRole(roleRequest);”上抛出了一个错误


错误,只是行号没有太多线索。

我目前正在使用以下过程从我的S3存储桶下载图像并存储它们,以将图像的zip返回给用户。我不包括您的zip创建代码:

要将文件下载到临时服务器,必须首先获得对所需的
S3Object
的访问权限。在您的情况下,它是
slack.xlsx
存储在
slack automation
存储桶中

您提到要使用IAM角色提供给您的临时凭据。明智的做法是不在代码中披露凭据,同时确保提供给服务的凭据将自动刷新。您需要初始化
s3Client
像这样:

AmazonS3Client s3Client = new AmazonS3Client(new InstanceProfileCredentialsProvider());
InstanceProfileCredentialsProvider
从Amazon EC2实例元数据服务加载凭据(基于您的IAM角色)

注意:确保正在使用的IAM角色实际具有对存储桶的读取权限

要获取
S3Object
,请使用以下命令:

S3Object fileObject = s3Client.getObject(new GetObjectRequest(bucketName, key));
在您的例子中,
bucketName
将是slackautomation,键将是S3 bucket上的文件名(这里是slack.xlsx)

然后,要将文件存储在服务器上,请使用
org.apache.commons.io.FileUtils中的
copyInputStreamToFile
函数

FileUtils.copyInputStreamToFile(s3Object.getObjectContent(), new File(fileName));

以上问题的解决方案,我在这里写完整的代码

public void setupWorkbook(String filePath) throws IOException {



   // String bucketName = "slack-automation";
    String key = "slack.xlsx";


    String fileName = "slack.xlsx";


    String bucketName = System.getenv("bucket_name");

    try {



        AmazonS3 s3Client = new AmazonS3Client();

        ObjectListing objects = s3Client.listObjects(bucketName);

        System.out.println("No. of Objects: " + objects.getObjectSummaries().size());
        S3Object fileObject = s3Client.getObject(new GetObjectRequest(bucketName, key));         
        InputStream in = new BufferedInputStream(fileObject.getObjectContent());

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        byte[] buf = new byte[1024];

        int n = 0;

        while (-1 != (n = in.read(buf))) {

            out.write(buf, 0, n);

        }

        out.close();
        in.close();
        byte[] response = out.toByteArray();
        FileOutputStream fos = new FileOutputStream("/tmp/" + fileName);

        fos.write(response);

        fos.close();
        file = new File("/tmp/" + fileName);

        //file = new File(filePath);

        inputStream = new FileInputStream(file);

        workBook = new XSSFWorkbook(inputStream);

        workBookSheet = workBook.getSheet(workBook.getSheetName(0));

        rowCount = workBookSheet.getPhysicalNumberOfRows();

        formatter = new DataFormatter();


    }
    catch(AmazonServiceException e) {
        // The call was transmitted successfully, but Amazon S3 couldn't process 
        // it, so it returned an error response.
        e.printStackTrace();
        System.out.println("FIRST EXCEPTION"+e.getMessage());
    }
    catch(SdkClientException e) {
        // Amazon S3 couldn't be contacted for a response, or the client
        // couldn't parse the response from Amazon S3.
        e.printStackTrace();
        System.out.println("SECOND EXCEPTION"+e.getMessage());
    }
只是需要添加代码的这一部分

   AmazonS3 s3Client = new AmazonS3Client();

    ObjectListing objects = s3Client.listObjects(bucketName);

    System.out.println("No. of Objects: " + objects.getObjectSummaries().size());
    S3Object fileObject = s3Client.getObject(new GetObjectRequest(bucketName, key));         
    InputStream in = new BufferedInputStream(fileObject.getObjectContent());

行“AmazonS3 s3Client=newamazons3client()”将担任IAM角色,并将在不传递我的accesskey和secretkey的情况下获取临时凭据,因为代码是从AWS Lambda运行的。就这样,谢谢大家的帮助

我已使用您建议的更改修改了我的问题,但仍然无法工作@SinarK.K发生的错误是什么?能否发布错误消息您可能遇到的问题?很高兴听到您现在有了问题的解决方案。如果您觉得我的答案有帮助或正确,请相应地投票或接受我的答案。如果需要,请在单独的答案中发布完整的解决方案,而不只是编辑问题,以便其他人从中受益。谢谢,我已获得正确的答案同样,我会上传答案