相关文章推荐
旅行中的充值卡  ·  TortoiseMerge ...·  1 年前    · 
礼貌的消炎药  ·  Blazor ...·  1 年前    · 
老实的鸵鸟  ·  kubeadm init curl ...·  1 年前    · 

在Spring boot应用程序中从Amazon S3桶中的某个文件夹下载文件时获得403

1 人关注

我正在为我的Spring boot应用程序使用一个S3桶。

在这里,我创建了一个文件夹,并在S3 bucket中上传了文件,这些文件来自我的Spring boot应用程序,并得到了以下 upload 函数的帮助。现在,当我列出文件夹中的文件时,我能够看到它们。但我不能下载它们,总是得到403。

上传、列出对象和下载的代码片段。

   //Download is failing
    public File downloadObject(String filePath) {
        File file = null;
        log.info("Downloading object {} from s3 bucket {}", filePath, bucketName);
        try {
          file = File.createTempFile(filePath, "");
          file.deleteOnExit();
          amazonS3.getObject(new GetObjectRequest(bucketName, filePath), file);
        } catch (Exception exception) {
          exception.stackTrace();
        return file;
      //Following function is working perfectly fine
      public List<String> listObjects(String pathPrefix) {
        final ListObjectsV2Result listingResponse = amazonS3.listObjectsV2(new ListObjectsV2Request()
            .withPrefix(pathPrefix)
            .withBucketName(bucketName));
        if (Objects.nonNull(listingResponse)) {
          List<String> result = listingResponse.getObjectSummaries().stream().map(
              S3ObjectSummary::getKey).collect(
              Collectors.toList());
          result.remove(pathPrefix);
          return result;
        return Collections.emptyList();
    //uploading is also working fine
    public void uploadFile(InputStream inputStream, String filePath) 
    try {
      amazonS3.putObject(new PutObjectRequest(bucketName, filePath, inputStream, null));
    } catch (SdkClientException exception) {
      exception.stackTrace();

S3桶的权限如下。

"Version": "2012-10-17", "Statement": [ "Sid": "AllowAReadWriteAccessToBucket", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456:role/abcd" "Action": "s3:*", "Resource": "arn:aws:s3:::test-bucket/*"

你可以看到,根据桶的策略,我已经给了所有的权限。即使这样,为什么下载还是失败了,我也搞不清楚。请帮助。

spring
amazon-web-services
spring-boot
amazon-s3
Joy
Joy
发布于 2021-05-26
1 个回答
smac2020
smac2020
发布于 2021-05-26
0 人赞同

我注意到的第一件事是你在使用旧的V1版S3 API。亚马逊强烈建议转移到AWS SDK for Java V2。

AWS SDK for Java 2.x是对1.x版本代码库的一次重大重写。它建立在Java 8+之上,并增加了几个经常被要求的功能。其中包括对非阻塞I/O的支持以及在运行时插入不同的HTTP实现的能力。

亚马逊S3 V2 Java API在Spring应用程序中工作得很好。有一个多服务的例子,显示了S3 V2 Java API在Spring BOOT应用中的使用。在这个用例中,我们得到一个字节[]来传递给Amazon Rekognition服务。

为了从亚马逊S3桶中的一个对象中获取一个字节[](我想你在使用下载这个词的时候就是这个意思),你可以使用V2代码,比如这样。

public byte[] getObjectBytes (String bucketName, String keyName) {
    s3 = getClient();
    try {
        // Create a GetObjectRequest instance
        GetObjectRequest objectRequest = GetObjectRequest
                .builder()
                .key(keyName)
                .bucket(bucketName)
                .build();
        // Get the byte[] from this S3 object
        ResponseBytes<GetObjectResponse> objectBytes = s3.getObjectAsBytes(objectRequest);
        byte[] data = objectBytes.asByteArray();
        return data;
    } catch (S3Exception e) {
        System.err.println(e.awsErrorDetails().errorMessage());
        System.exit(1);
    return null;