Have problem accessing file using presigned url generated by aws sdk, given all necessary permission for the bucket.
I have downloaded the sample code from there github and changed the below
Awscredential provider as per my requirement.
The changes are below
AWSStaticCredentialsProvider *credentialsProvider =[[AWSStaticCredentialsProvider alloc] initWithAccessKey:S3AccessKey secretKey:S3secretKey];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
Even though i upload the file sucessfully to aws I am not able to access them using the presigned url which i get from the aws sdk while uploading.
Can anyone point out the things i am missing in order to access the files using presigned url.
when url is loaded in browser SignatureDoesNotMatch error is shown
The most possible reason for "SignatureDoesNotMatch" is the contents in header-field are different from the one provided while generating the presigned url.
Here is a code snippet to demonstrate how to generate and download a file by using presigned url:
AWSS3GetPreSignedURLRequest *getPreSignedURLRequest = [AWSS3GetPreSignedURLRequest new];
getPreSignedURLRequest.bucket = #"bucketname";
getPreSignedURLRequest.key = #"keyname";
getPreSignedURLRequest.HTTPMethod = AWSHTTPMethodGET;
getPreSignedURLRequest.expires = [NSDate dateWithTimeIntervalSinceNow:3600];
AWSS3PreSignedURLBuilder *preSignedURLBuilder = [AWSS3PreSignedURLBuilder defaultS3PreSignedURLBuilder];
[[[preSignedURLBuilder getPreSignedURL:getPreSignedURLRequest] continueWithBlock:^id(BFTask *task) {
if (task.error) {
XCTAssertNil(task.error);
return nil;
}
NSURL *presignedURL = task.result;
//NSLog(#"(GET)presigned URL is: %#",presignedURL.absoluteString);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:presignedURL];
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
NSError *returnError = nil;
NSHTTPURLResponse *returnResponse = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&returnResponse error:&returnError];
return nil;
}] waitUntilFinished];
The problem is with presigned url encoding. In iOS and android sdks (not in windows) you need to encode the query string in the Presigned url again.
NEWURL=baseurl +(encoded query String);
NEWURL is the correct url you can access.
it worked for me.
Try with this, you need to register PreSignedURL builder.
AWSStaticCredentialsProvider *credentialsProvider =[[AWSStaticCredentialsProvider alloc] initWithAccessKey:S3AccessKey secretKey:S3secretKey];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
// Register S3 PreSignedURL Builder
[AWSS3PreSignedURLBuilder registerS3PreSignedURLBuilderWithConfiguration:configuration forKey:#"configuration_name"];
AWSS3PreSignedURLBuilder * urlBuilder = [AWSS3PreSignedURLBuilder S3PreSignedURLBuilderForKey:#"configuration_name"];
Related
I am working on an app in which I need to upload image using AWSS3. Below is my code. However I am getting error something about pool id not found. I am not sure whats going, Do I need to add anything more.
This is the error getting
Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=10 "(null)" UserInfo={__type=ResourceNotFoundException, message=IdentityPool 'ap-northeast-1:xxxxxxx' not found
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId:#""];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
// get the image from a UIImageView that is displaying the selected Image
// create a local image that we can use to upload to s3
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:#"image.png"];
NSData *imageData = UIImagePNGRepresentation(selectedImage);
[imageData writeToFile:path atomically:YES];
// once the image is saved we can use the path to create a local fileurl
NSURL *url = [[NSURL alloc] initFileURLWithPath:path];
// next we set up the S3 upload request manager
AWSS3TransferManagerUploadRequest *_uploadRequest = [AWSS3TransferManagerUploadRequest new];
// set the bucket
_uploadRequest.bucket = #"chatify";
// I want this image to be public to anyone to view it so I'm setting it to Public Read
_uploadRequest.ACL = AWSS3ObjectCannedACLPublicRead;
// set the image's name that will be used on the s3 server. I am also creating a folder to place the image in
_uploadRequest.key = #"ios/image.png";
// set the content type
_uploadRequest.contentType = #"image/png";
// we will track progress through an AWSNetworkingUploadProgressBlock
_uploadRequest.body = url;
__weak ClaimViewController *weakSelf = self;
_uploadRequest.uploadProgress =^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend){
dispatch_sync(dispatch_get_main_queue(), ^{
weakSelf.amountUploaded = totalBytesSent;
weakSelf.filesize = totalBytesExpectedToSend;
[weakSelf update];
});
};
// now the upload request is set up we can creat the transfermanger, the credentials are already set up in the app delegate
AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
// start the upload
[[transferManager upload:_uploadRequest] continueWithExecutor:[AWSExecutor mainThreadExecutor] withBlock:^id(AWSTask *task) {
// once the uploadmanager finishes check if there were any errors
if (task.error) {
NSLog(#"%#", task.error);
}else{// if there aren't any then the image is uploaded!
// this is the url of the image we just uploaded
NSLog(#"https://s3.amazonaws.com/s3-demo-objectivec/foldername/image.png");
}
return nil;
}];
hi #kashif the error clear says that you need to add the pool id
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId:#""];
but in the Above code you just pass the Black in identityPoolId
Here's also another method to which provide Credential
AWSStaticCredentialsProvider *credentialsProvider = [AWSStaticCredentialsProvider credentialsWithAccessKey:#"AccessKey" secretKey :#"secretKey"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSWest2
credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
This error is because of your Cognito Identity Pool being deleted from your account or you setting the region incorrectly. Your region should be set to
AWSRegionAPNorthEast1 based on what I see in the posted code.
Thanks,
Rohan
Before I asked question, I tried to find solution by google but didn't get answer so writing here
I’ve followed all steps that describe in this link.
But I am getting (null) response after all call using
AWSTask *task = [serviceClient myAPI : “Parameter”];
But when I tried invoke URL in postman with its - AccessKey, SecretKey, AWS Region, Service Name - parameters, I am getting proper response.
(My api key is disabled)
EDITED:
When i’ve used below code then I was getting (null) response.
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId:#"YourIdentityPoolId"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSWest2 credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
But when using below code then got Blank/Nothing response.
AWSStaticCredentialsProvider *credentialsProvider = [[AWSStaticCredentialsProvider alloc] initWithAccessKey:#“KEY” secretKey:#“KEY”];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSWest2 credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
Anybody will help me to solve my issue?
I am new to using AWS as a backend for my iOS mobile app. I have set up all the roles and identiy pool needed. I have added the following code to my AppDelegate.m file:
// Starting AWS
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId:#"IdentityPool"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
What is the next step to see if I am authenticated or not? Trying to figue out iOS code to see what role I am in.
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
Import service headers where you want to use AWS and then just try to make a call to AWS services.
AWSS3Transfermanager *transferManager = [AWSS3Transfermanager defaultS3TransferManager];
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.bucket = yourBucket;
uploadRequest.key = yourKey;
uploadRequest.body = yourDataURL;
uploadRequest.contentLength = [NSNumber numberWithUnsignedLongLong:fileSize];
[[transferManager upload:uploadRequest] continueWithBlock:^id(AWSTask *task) {
// Do something with the response
return nil;
}];
I try to upload file to s3 and I always got next error message
2015-08-05 14:35:53.931 BellyBuds[47981:2189296] Upload failed: [Error
Domain=com.amazonaws.AWSS3ErrorDomain Code=0 "The operation couldn’t
be completed. (com.amazonaws.AWSS3ErrorDomain error 0.)"
UserInfo=0x7fd40a40d8f0
{HostId=wo/bHFvnQjGuiLic3IhL+jicVfeIcuR6M4HXz/nB9WRt/T09h16bbR77nkqKngzj,
Bucket=bbbname, Endpoint=bbstagemusic.s3.amazonaws.com,
Message=The bucket you are attempting to access must be addressed
using the specified endpoint. Please send all future requests to this
endpoint., Code=PermanentRedirect, RequestId=6D250A718C640210}]
AWSCognitoCredentialsProvider *credProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
identityId:[params valueForKey:#"IdentityId"]
identityPoolId:[params valueForKey:#"IdentityPoolId"]
logins:#{#"cognito-identity.amazonaws.com": params[#"Token"]}];
//credProvider.logins = #{ #(AWSCognitoLoginProviderKeyLoginWithAmazon): params[#"Token"] };
AWSServiceConfiguration *serviceConfiguration = [[AWSServiceConfiguration alloc]initWithRegion:AWSRegionUSEast1 credentialsProvider:credProvider];
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.body = [NSURL fileURLWithPath:[BBFileManager getRecordingList][0]];
uploadRequest.key = [[BBFileManager getRecordingList][0] lastPathComponent];
uploadRequest.bucket = #"bbbucket";
AWSServiceManager *serv = [AWSServiceManager defaultServiceManager];
serv.defaultServiceConfiguration = serviceConfiguration;
[AWSS3TransferManager registerS3TransferManagerWithConfiguration:serviceConfiguration forKey:#"transferKey"];
[[[AWSS3TransferManager S3TransferManagerForKey:#"transferKey"] upload:uploadRequest] continueWithBlock:^id (AWSTask *task) {
return nil;
}];
I use correct data and set right region. I try use other regions and make other stuff, but this not be helpful. I always got errors related to regions and endpoint. What I do wrong?
I've found the problem!
uploadRequest.key = [[BBFileManager getRecordingList][0] lastPathComponent];
property uploadRequest.key should contain future file path for example, if future file will be located at /bbucketname/music/IdentityId/file.mp3, value of the key should be music/IdentityId/file.mp3
I'm trying to upload file on S3 bucket and device is getting access information from another server (AWSAccessKeyId and Signature). Is it possible to upload file with AWS iOS SDK v2? If not are there any chances to use another approach possible for iOS (eg. generate Pre-Signed URL and do the http post/put)?
Right now I'm using this approach, but it's for access_key/access_secret:
AWSStaticCredentialsProvider *credentialsProvider = [AWSStaticCredentialsProvider credentialsWithAccessKey:awsAccessKey secretKey:awsSecretKey];
AWSServiceConfiguration *configuration = [AWSServiceConfiguration configurationWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
AWSS3 *transferManager = [[AWSS3 alloc] initWithConfiguration:configuration];
AWSS3PutObjectRequest *getLog = [[AWSS3PutObjectRequest alloc] init];
getLog.bucket = awsS3Bucket;
getLog.key = awsS3FileNameString;
getLog.contentType = #"text/plain";
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:logFileName];
long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:fileName error:nil][NSFileSize] longLongValue];
getLog.body = [NSURL fileURLWithPath:fileName];
getLog.contentLength = [NSNumber numberWithUnsignedLongLong:fileSize];
[[transferManager putObject:getLog] continueWithBlock:^id(BFTask *task) {
if(task.error)
{
NSLog(#"Error: %#",task.error);
}
else
{
NSLog(#"Got here: %#", task.result);
}
return nil;
}];
I'll be grateful for any ideas.
I recommend the following approach:
Generate the access key, secret key, and session token on your server. You have many language options including Java, .NET, PHP, Ruby, Python, and Node.js.
Implement your own credentials provider by conforming to AWSCredentialsProvider. This credentials provider should:
Retrieve the access key, secret key, and session key from your server.
Persist them until they expire.
Return the credentials when requested.
If they are expired, re-retrieve them from your server.
Calling refresh also should initiate the credentials retrieval process.
Assign your credentials provider to defaultServiceConfiguration or pass it to initWithConfiguration:.
As a side note, when using initWithConfiguration:, you need to manually retain a strong reference to an instance of AWSS3. Using defaultS3 will eliminate the need for this.
Hope this helps,