3

We have a requirement to upload files/attachments on CASE record (using custom drag and drop section) from Service Cloud to AWS S3. We ran into file size limit issue with files bigger than 12 MB. Since the upload process is asynchronous process, it goes through for files of size up-to 12 MB and we are OK with that. But, we are unable to download files which are bigger than 6 MB (synchronous call). Reason for downloading the files instead of using full context URL to AWS is, it's a client/browser call and exposes Secret key information. Please advise if there is a way to download files up-to 12 MB (atleast) via server call from Apex. All we know and have is AWS host URL, Bucket Name, Secret Key and Access Key. Any help is greatly appreciated!

2

This is demonstrated in the Amazon Toolkit. AWS allows you to create a pre-signed URL that does not expose your secret key. You can leverage this to upload and download files from S3 without exposing your secrets client-side. You'll want to read the manual for specifics. Here's the description from the documentation:

A pre-signed URL gives you access to the object identified in the URL, provided that the creator of the pre-signed URL has permissions to access that object. That is, if you receive a pre-signed URL to upload an object, you can upload the object only if the creator of the pre-signed URL has the necessary permissions to upload that object.

All objects and buckets by default are private. The pre-signed URLs are useful if you want your user/customer to be able upload a specific object to your bucket, but you don't require them to have AWS security credentials or permissions. When you create a pre-signed URL, you must provide your security credentials, specify a bucket name, an object key, an HTTP method (PUT for uploading objects), and an expiration date and time. The pre-signed URLs are valid only for the specified duration.

You can generate a pre-signed URL programmatically using the AWS SDK for Java or the AWS SDK for .NET. If you are using Visual Studio, you can also use AWS Explorer to generate a pre-signed object URL without writing any code. Anyone who receives a valid pre-signed URL can then programmatically upload an object.

You can also choose to upload file parts, which basically goes like this: StartMultipartUpload, UploadParts, FinishMultipartUpload. I haven't gotten this working in Apex Code, as it is pretty tricky to get just right, but it's all there in the documentation.

Finally, you can use the Range header on the GET Object to download parts of the file at a time, and figure out a way to recombine them later. This is also tricky without running into memory limits, but possible with some client-side effort.

  • Thank you for the information. If I understand this correctly, Signed URL will not have secret key but it does expose Access Key. Am i correct? – srikanth pasupuleti Sep 25 '16 at 6:26
  • 1
    @srikanthpasupuleti as I recall, yes, the access key is part of the url. However, the access key is useless without the secret key. It's like exposing your username but but not your password. It's perfectly safe. – sfdcfox Sep 25 '16 at 6:28
  • 1
    We did implement it in that way but customer doesn't want AccessKey to be exposed either. Another reason for not looking at client/browser call is, Customer is going to white list (restrict access to) Salesforce IP addresses which would prevent Pre-Signed URL (browse specific call) being accessible. So, we tried downloading the binary file from AWS using a POST call ( Server call) but it's limited to 6 MB. I will try to educate customer about security with Pre-Signed URL but Do you have any thoughts about downloading the bigger files via server call or process we are following here. – srikanth pasupuleti Sep 25 '16 at 15:32
1

Amazon allows you to create signed policies and URLs so you don't expose your secret keys to the client. You can then upload or download straight from the browser without going through Salesforce servers. You can even set a close expiration date on that URL's so the links cannot be shared by users.

The java sample would be the best example for you to get it ported over to Apex.

  • Thank you for the info. We actually want to download the files via Salesforce servers. is there a way to get rid of 6MB limitation still going via server call? – srikanth pasupuleti Sep 25 '16 at 16:19
0

Referring the Sync Apex call to download more than 6MB file at Salesforce, I would suggest trying post the recordId from Salesforce to AWS and write a script at AWS to call standard Salesforce APIs to upload file to Salesforce from AWS.

Refer below documentation: - https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_insert_update_blob.htm

I haven't tried this but this should work ideally.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.