从 AWS S3 下载文件访问被拒绝
Download File from AWS S3 Access Denied
嗨,我正在尝试使用亚马逊网络服务为我的 iOS 应用程序存储文件。
这是我用来下载存储在 aws S3 上的文件的代码
我将以下内容添加到 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;
然后在我的 class 中,我使用以下方法下载对象。请注意,没有对对象应用加密,并且对存储桶的所有权限都已解锁
- (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(), ^{
});
}];
}
虽然我已经把所有的权限都允许了。阻止所有 public 访问已关闭,我不断收到以下错误:
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=}
我已应用此视频中的所有建议:
Why am I getting an Access Denied error from the Amazon S3 console while I modify a bucket policy? - YouTube
在云端尝试以下命令 shell 没有显示任何错误:
aws s3 cp s3://<bucket name>/<key> /tmp/localfile
如果需要任何进一步的代码或信息,请告诉我。
首先,让我们排除编码。尝试使用 AWS CLI 本机访问该文件。直接向上 aws s3 cp s3://<bucket name>/<key> /tmp/localfile
如果这有效,则说明您遇到了代码问题,我们会继续检查。如果它不起作用,您可能有权限问题。
要检查的第二件事 - 您是否使用加密?有可能(根据我的经验)虽然您可能有权访问 S3 存储桶,但您可能无权访问加密密钥,因此您获得的访问被拒绝实际上来自 KMS。您可能需要授予解密 KMS 密钥的权限。
您似乎正在使用 Cognito 作为凭据提供程序。据我了解,即使对于 public 个存储桶,如果您通过 API 访问,您也需要设置适当的 IAM 角色和权限。这意味着为 IAM 角色 分配对 身份池 中 身份池 内的 已验证身份 的 S3 访问权限18=]认知.
或者,您必须通过no-sign-request
。至少在 CLI 中你必须这样做。 https://docs.aws.amazon.com/cli/latest/reference/.
但如果您使用 URL 访问,使用 public 个存储桶,您将能够获取对象。
在 cognito 身份池中,您可以指定两个 IAM 角色(甚至更多,但让我们关注默认的两个):
- 未经身份验证的角色 - 分配给未登录身份提供者的用户的角色
- 经过身份验证的角色 - 分配给经过身份验证的用户的角色
Cognito 创建的默认角色不提供对 S3 存储桶的访问权限 - 您必须修改策略并添加缺少的权限(即 s3:PutObject、s3:GetObject、s3:ListBucket)
如果您的存储桶使用 KMS 密钥加密,您的角色策略或密钥策略必须允许 kms 操作(即 kms.Encrypt、kms:Decrypt、kms:generateKeyData)
尝试在您的应用程序中调用 sts getCallerIdentity 操作并检查 returned 身份,它应该 return 经过身份验证的角色 ARN。
如果是这样,请将缺少的访问 S3 存储桶和 KMS 密钥的权限添加到 returned 角色策略。
嗨,我正在尝试使用亚马逊网络服务为我的 iOS 应用程序存储文件。
这是我用来下载存储在 aws S3 上的文件的代码
我将以下内容添加到 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;
然后在我的 class 中,我使用以下方法下载对象。请注意,没有对对象应用加密,并且对存储桶的所有权限都已解锁
- (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(), ^{
});
}];
}
虽然我已经把所有的权限都允许了。阻止所有 public 访问已关闭,我不断收到以下错误:
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=}
我已应用此视频中的所有建议: Why am I getting an Access Denied error from the Amazon S3 console while I modify a bucket policy? - YouTube
在云端尝试以下命令 shell 没有显示任何错误:
aws s3 cp s3://<bucket name>/<key> /tmp/localfile
如果需要任何进一步的代码或信息,请告诉我。
首先,让我们排除编码。尝试使用 AWS CLI 本机访问该文件。直接向上 aws s3 cp s3://<bucket name>/<key> /tmp/localfile
如果这有效,则说明您遇到了代码问题,我们会继续检查。如果它不起作用,您可能有权限问题。
要检查的第二件事 - 您是否使用加密?有可能(根据我的经验)虽然您可能有权访问 S3 存储桶,但您可能无权访问加密密钥,因此您获得的访问被拒绝实际上来自 KMS。您可能需要授予解密 KMS 密钥的权限。
您似乎正在使用 Cognito 作为凭据提供程序。据我了解,即使对于 public 个存储桶,如果您通过 API 访问,您也需要设置适当的 IAM 角色和权限。这意味着为 IAM 角色 分配对 身份池 中 身份池 内的 已验证身份 的 S3 访问权限18=]认知.
或者,您必须通过no-sign-request
。至少在 CLI 中你必须这样做。 https://docs.aws.amazon.com/cli/latest/reference/.
但如果您使用 URL 访问,使用 public 个存储桶,您将能够获取对象。
在 cognito 身份池中,您可以指定两个 IAM 角色(甚至更多,但让我们关注默认的两个):
- 未经身份验证的角色 - 分配给未登录身份提供者的用户的角色
- 经过身份验证的角色 - 分配给经过身份验证的用户的角色
Cognito 创建的默认角色不提供对 S3 存储桶的访问权限 - 您必须修改策略并添加缺少的权限(即 s3:PutObject、s3:GetObject、s3:ListBucket)
如果您的存储桶使用 KMS 密钥加密,您的角色策略或密钥策略必须允许 kms 操作(即 kms.Encrypt、kms:Decrypt、kms:generateKeyData)
尝试在您的应用程序中调用 sts getCallerIdentity 操作并检查 returned 身份,它应该 return 经过身份验证的角色 ARN。 如果是这样,请将缺少的访问 S3 存储桶和 KMS 密钥的权限添加到 returned 角色策略。