我创建了一个 AWS IAM 用户并使用 S3 Bucket 策略授予该用户对特定存储桶及其相关对象的所有权限,如下所示(使用 X 的地方应该有一些特定的标识符)。该用户可以以编程方式(AWS JAVA SDK)添加(上传)和删除此存储桶中的文件,但我很困惑为什么他无法下载任何文件。我知道这里有人问过这样的问题,但似乎问题在于他没有指定我已经完成的存储桶级别访问。下面是 S3 存储桶策略。
{
"Version": "2012-10-17",
"Id": "PolicyXXXXXXXXXXXXX",
"Statement": [
{
"Sid": "StmtXXXXXXXXXXXXX",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXXXXXX:user/username"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::bucketName"
},
{
"Sid": "StmtXXXXXXXXXXXXX",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXXXXXX:user/username"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::bucketName/*"
}
]
}
下面是下载源代码
public void downloadS3(String bucketName, String accessKey, String secretKey, String urlString)
throws AmazonServiceException, AmazonClientException, IOException {
BasicAWSCredentials creds = new BasicAWSCredentials(accessKey, secretKey);
System.out.println("bucket Name:"+bucketName);
AmazonS3 s3 = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(creds))
.withRegion(Regions.US_EAST_2).build() ;
//The urlString is the s3 object url saved in database
URL url = new URL(urlString);
String key=(FilenameUtils.getName(url.getPath())); // -> file.extension
System.out.println("Downloading an object file with name:"+key);
//This returns an ObjectMetadata file which we don't need to use it in this case
//ObjectMetadata object =
s3.getObject(new GetObjectRequest(bucketName, key), new File(key));
/*end downloading logic*/
System.out.println("File "+key+" Downloaded succesifully ");
}
public void downloadFile(String urlString) {
ExecutorService service = Executors.newFixedThreadPool(4);
service.submit(new Runnable() {
public void run() {
try {
this.downloadS3("bucket",accessKey,secretKey,urlString);
} catch (AmazonServiceException ase) {
System.err
.println("Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.");
System.err.println("Error Message: " + ase.getMessage());
System.err.println("HTTP Status Code: " + ase.getStatusCode());
System.err.println("AWS Error Code: " + ase.getErrorCode());
System.err.println("Error Type: " + ase.getErrorType());
System.err.println("Request ID: " + ase.getRequestId());
} catch (AmazonClientException ace) {
System.err
.println("Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.");
System.err.println("Error Message: " + ace.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
下面是我得到的一个例外
Caught an AmazonClientException, which means the client encountered a serious internal problem while trying to communicate with S3, such as not being able to access the network.Error Message: java.io.FileNotFoundException: fileName.mp3 (Permission denied)
记住文件实际上在那里(相同的键)。
我还为用户定义了 IAM 策略(内联策略)(如下所示),但同样的问题仍然存在。在此先感谢您的帮助。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::*"
]
}
]
}