有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

将文件上载到Amazon S3时发生java(权限被拒绝)]

我正在尝试将一个文件上载到AmazonS3。它在本地运行正常,但在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权限


共 (3) 个答案

  1. # 1 楼答案

    在Elastic Beanstalk中部署时,我收到了“权限被拒绝”错误。”

    您可以参考AWS示例,这些示例描述了如何使用Java编写的web应用程序将给定文件从桌面上传到Amazon S3存储桶。因为使用了Java(Spring BOOT应用程序),所以可以使用AWS SDK for Java V2

    Creating an example AWS photo analyzer application using the AWS SDK for Java

    在本例中,请注意该应用程序已部署到Elastic Beanstalk。Amazon S3服务客户端是这样创建的:

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

    在Elastic Beanstalk上,通过定义以下变量,可以将您的creds设置为具有Amazon S3权限的IAM角色:

    • AWS\u访问\u密钥\u ID
    • AWS_密码_访问_密钥

    现在,您可以使用S3服务客户端使用以下Java逻辑将文件放入Amazon S3存储桶:

    // 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. # 3 楼答案

    可以构造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");
        }
    

    希望这篇文章能帮助你继续,快乐编码