'Download File from AWS S3 Access Denied
Hy, I am trying to use Amazon web service to store files for my iOS App.
Here's the code I am using to download the file stored on aws S3
I added the following to the appDelegate
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc]
initWithRegionType:AWSRegionUSEast2
identityPoolId:@"us-east-2:3764e0f9-khu97-4844-b9f7-57defdfjv8b8b"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast2 credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
Then in my class I used the following to download the object. Kindly note that no encryption is applied to the object and all permissions are unblocked for the bucket
- (void)downloadImageToAWS{
// AWS Configurations
AWSS3DownloadHelper *aws = [[AWSS3DownloadHelper alloc] init];
aws.bucket = @"my-sample-bucket-002";
aws.key = @"photo-sam-002.jpg";
// AWS progress block
aws.progressBlock = ^(AWSS3TransferUtilityTask *task, NSProgress *progress) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"progress.fractionCompleted %f", progress.fractionCompleted);
});
};
// AWS completionHandler
[self addAWSDownloadComplitionHandler:aws];
// Update UI if job / task can upload a file on AWS S3
[self successfulDownloadOfAWSS3ByCompletionHandler:aws.completionHandler withProgressBlock:aws.progressBlock];
[aws downloadAWSFile];
}
- (void) addAWSDownloadComplitionHandler:(AWSS3DownloadHelper *)aws {
// Create instance to View Controller
NSLog(@"addAWSDownloadComplitionHandler");
aws.completionHandler = ^(AWSS3TransferUtilityDownloadTask *task, NSURL *location, NSData *data, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"Unsuccessfully downloaded error %li", (long)[error code]);
NSLog(@"Unsuccessfully downloaded error %@", [error description]);
}
else if (data) {
NSLog(@"data %@", data);
}
});
};
}
- (void) successfulDownloadOfAWSS3ByCompletionHandler:(AWSS3TransferUtilityDownloadCompletionHandlerBlock)completionHandler withProgressBlock:(AWSS3TransferUtilityProgressBlock)progressBlock {
NSLog(@"successfulDownloadOfAWSS3ByCompletionHandler");
AWSS3TransferUtility *transferUtility = [AWSS3TransferUtility defaultS3TransferUtility];
[transferUtility enumerateToAssignBlocksForUploadTask:nil downloadTask:^(AWSS3TransferUtilityDownloadTask * _Nonnull downloadTask, AWSS3TransferUtilityProgressBlock _Nullable __autoreleasing * _Nullable downloadProgressBlockReference, AWSS3TransferUtilityDownloadCompletionHandlerBlock _Nullable __autoreleasing * _Nullable completionHandlerReference) {
NSLog(@"taskIdentifier %lu", (unsigned long)downloadTask.taskIdentifier);
*downloadProgressBlockReference = progressBlock;
*completionHandlerReference = completionHandler;
dispatch_async(dispatch_get_main_queue(), ^{
});
}];
}
Although I have put all permissions to allow. Block all public access is turned off, I keep getting the following error:
Domain=com.amazonaws.AWSS3TransferUtilityErrorDomain Code=2 "(null)" UserInfo={Server=AmazonS3, Error={
Code = AccessDenied;
HostId = "SJABFLSKBtprmLRaHLjjockzjfubejlakhipjaKDNSAFJLB4ViE=";//Changed
Message = "Access Denied";
RequestId = jabduw2dhC6WCT;//changed
}, Transfer-Encoding=Identity, Content-Type=application/xml, Date=Wed, 29 Dec 2021 09:33:06 GMT, x-amz-request-id=2TJSHCJ2ASTC6WCT, x-amz-id-2=Fbg2cDXwU5wLgQLHbGtprmLRaHLjjocvZzCcUNfMrSpT5Oiwl3LjEkpPQ2OBzLmBrKXnrwq4ViE=}
I have applied all suggestions in this video: Why am I getting an Access Denied error from the Amazon S3 console while I modify a bucket policy? - YouTube
Trying the following command on the cloud shell didn't show any error:
aws s3 cp s3://<bucket name>/<key> /tmp/localfile
If any further code or info is needed kindly let me know.
Solution 1:[1]
Firstly, let's rule out coding. Try to access the file natively using the AWS CLI. Just a straight up aws s3 cp s3://<bucket name>/<key> /tmp/localfile
If this works, you've got a code issue, and we continue checking. If it does not work, you may have a permissions issue.
The 2nd thing to check - are you using encryption? Chances are (from my experience) that while you may have permissions to access the S3 bucket, you may not have permissions to access the encryption key, so the access denied you're getting is actually coming from KMS. You may need to allow the right to decrypt the KMS key.
Solution 2:[2]
In cognito Identity pool you can specify two IAM Roles (even more, but lets focus on default two):
- Unauthenticated role - the role assigned to user which is not logged in to Identity Provider
- Authenticated role - the role assigned to authenticated user
Default roles created by Cognito don't provide access to S3 buckets - you have to modify policy and add missing permissions (i.e. s3:PutObject, s3:GetObject, s3:ListBucket)
If your bucket is encrypted with KMS key, your role policy or key polisy must allow kms actions (i.e. kms.Encrypt, kms:Decrypt, kms:generateKeyData)
Try to invoke sts getCallerIdentity action in your app and check returned identity, it should return Authenticated role ARN. If so, add missing permissions to access S3 bucket and KMS key to returned role policy.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Phil Massyn |
| Solution 2 | Tomasz Bre? |
