(В разрешении отказано)] произошло во время загрузки файла в Amazon S3

#java #amazon-web-services #spring-boot #amazon-s3

Вопрос:

Я пытаюсь загрузить файл в Amazon S3. Он отлично работает в моем локальном, но я получаю ошибку «отказано в разрешении» во время его развертывания в Elastic Beanstalk.

Мой код:

 public String uploadFileToS3BucketTemp(ByteArrayOutputStream baos, boolean enablePublicReadAccess, String filename, String path) 
    {
        LocalDateTime localDate = LocalDateTime.now();
        String currentDateTime = CommonFunctions.customDateFormatter(CommonFunctions.getCurrentDateTime(), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");

        Date date = new Date();
        //Pattern for showing milliseconds in the time "SSS"
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        String str = sdf.format(date);
        
        String time = str.split("\s")[1].split("\.")[0];
        String currentTime =  time.replaceAll(":", "-");
        String fileName = filename "-" currentDateTime "-"  currentTime  ".xls";
        String filePath = "";

        try {

            File file = new File(filePath fileName);
        
            FileOutputStream fos = new FileOutputStream(file);

            baos.writeTo(fos);
            fos.close();
            
            InputStream is=new FileInputStream(file);
            
            
            s3Client.putObject(new PutObjectRequest(bucketName, path "/" fileName, is, new ObjectMetadata()));
            
        } catch (IOException | AmazonServiceException ex) {
            logger.error("error ["   ex.getMessage()   "] occurred while uploading ["   fileName   "] ");
        }
        
        String url = signedUrl(path "/" fileName);
        
        return url;
    }
 

При проверке журналов сервера он показывает мне следующую ошибку:

 ERROR 25491 (Permission denied)] occurred while uploading
 

Ведро не является общедоступным. У ElasticBeantsalk есть роль IAM, которая имеет разрешение AmazonS3FullAccess

Комментарии:

1. Покажите код, в котором вы создаете s3Client

2. Не могли бы вы показать нам полис на ведре. Иногда это может относиться к спискам управления доступом

Ответ №1:

«Я получаю ошибку»Отказано в разрешении», когда он развернут в эластичном бобовом стебле».

Вы можете сослаться на примеры AWS, в которых описывается, как загрузить данный файл с рабочего стола в корзину Amazon S3 с помощью веб-приложения, написанного на Java. Поскольку используется Java (приложение для весенней загрузки), вы можете использовать AWS SDK для Java V2.

Создание примера приложения AWS photo analyzer с использованием пакета SDK AWS для Java

В этом примере обратите внимание, что приложение развернуто в Elastic Beanstalk. Клиент службы Amazon S3 создается следующим образом:

  S3Client s3 = S3Client.builder()
            .credentialsProvider(EnvironmentVariableCredentialsProvider.create())
            .region(region)
            .build();
 

В Elastic Beanstalk вы можете установить для своих учетных записей роль IAM с разрешениями Amazon S3, определив эти переменные:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

Теперь вы можете использовать клиент службы S3 для размещения файла в корзине Amazon S3, используя эту логику Java:

 // Places an image into a S3 bucket.
public String putObject(byte[] data, String bucketName, String objectKey) {

    s3 = getClient();

    try {
        PutObjectResponse response = s3.putObject(PutObjectRequest.builder()
                        .bucket(bucketName)
                        .key(objectKey)
                        .build(),
                RequestBody.fromBytes(data));

        return response.eTag();

    } catch (S3Exception e) {
        System.err.println(e.getMessage());
        System.exit(1);
    }
    return "";
}
 

Ответ №2:

Вы можете построить AmazonS3 объект для того, чтобы вызвать вызов API putObject() . Есть два способа,

—> Вы можете предоставить учетные данные и построить > AmazonS3 (Не рекомендуется для развертывания в облаке)

     AWSCredentials awsCredentials = new BasicAWSCredentials(aws_access_key, aws_secret_key);
    return AmazonS3ClientBuilder
            .standard()
            .withRegion("ap-south-1")
            .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
            .build();
 

—> Вы можете предоставить учетные данные через > AWS IAM роль. (Рекомендуется)

     InstanceProfileCredentialsProvider provider = new InstanceProfileCredentialsProvider(true);
    return AmazonS3ClientBuilder.standard()
            .withCredentials(provider)
            .build();
 

Предполагается, что вы должны предоставить соответствующее разрешение для S3. (в этом примере для вызова putObject() )

—> > putObject() Вызов API будет выглядеть так, как показано ниже в блоке кода.

   public void upload(String thePath, String theFileName, Optional<Map<String, String>> theOptionalMetaData,
                       InputStream inputStream) {
        printLog("upload(): Executed with path - "   thePath   " and file name - "   theFileName);
        ObjectMetadata objectMetadata = new ObjectMetadata();
        theOptionalMetaData.ifPresent(map -> {
            //Loops through the optionalMetaData map adding all of the file information to the S3 objectMetaData.
            if (!map.isEmpty()) {
                map.forEach(objectMetadata::addUserMetadata);
            }
        });
        printLog("upload(): Done adding metadata");

        try {
            //Saves the file to Amazon S3 bucket
            amazonS3.putObject(thePath, theFileName, inputStream, objectMetadata);
        }
        catch (AmazonServiceException exception) {
            printLog("upload(): Exception upon uploading file");
            throw new IllegalStateException("Exception upon uploading file", exception);
        }
        printLog("upload(): File upload successful");
    }
 

Надеюсь, этот пост поможет вам продолжить, счастливого кодирования!

Ответ №3:

Я бы рекомендовал вам проверить свой профиль экземпляра ec2 и политику корзины s3.

Убедитесь, что профиль экземпляра имеет доступ к S3, а политика корзины S3 разрешает объекты, помещенные из профиля экземпляра.

https://aws.amazon.com/premiumsupport/knowledge-center/elastic-beanstalk-s3-bucket-instance/