You need to sign in to do that
Don't have an account?
Anil_Vaishnav
How to generate AWS cloudfront singed url in apex?
I am trying to generate AWS Cloudfront singed url using apex but every time get Access Denied.
public url is working fine. i.e. jueh890044563.cloudfront.net/test.pdf
But I need a singed url of cloudfront.
I have already done following things in AWS.
S3 bucket is private.
test.pdf is private.
Created cloudfront Distribution (domain name is : jueh890044563.cloudfront.net)
Apex code
String keyPairId = 'YTEHJLKFHHRKF';
Datetime now = DateTime.now();
Datetime expireson = now.addDays(2);
Long Lexpires = expireson.getTime()/1000;
String policyStatement = '{"Statement":[{"Resource":"jueh890044563.cloudfront.net/test.pdf","Condition":{"DateLessThan":{"AWS:EpochTime":'+Lexpires+'}}}]}';
policyStatement = EncodingUtil.base64Encode(Blob.valueOf(policyStatement));
String privateKey = 'dfgdfgtgdfgdfgdfsgdfgdfsgdfgdfgdfgsdf'+
'dfgdfgdfgdfgdfgdfgdfgdfgdfgfgdfgdfsdf'+
'dfdfgdfgdfgdfgdfgfdgdfg/i0AB1Jz20QlGy'+
'dsfgdfgdfgdfgdfgdfgdsfgdfgdfgffdfgdfg';
Blob mac = Crypto.generateMac('HmacSHA1', blob.valueof(policyStatement),blob.valueof(privateKey));
String signed = EncodingUtil.base64Encode(mac);
String downloadUrl = 'jueh890044563.cloudfront.net/test.pdf?Policy='+policyStatement+'&Signature='+signed+'&Key-Pair-Id='+keyPairId;
Is downloadUrl is singedUrl? When we run this url then return Access Denied.
Thanks in advance.
public url is working fine. i.e. jueh890044563.cloudfront.net/test.pdf
But I need a singed url of cloudfront.
I have already done following things in AWS.
S3 bucket is private.
test.pdf is private.
Created cloudfront Distribution (domain name is : jueh890044563.cloudfront.net)
Apex code
String keyPairId = 'YTEHJLKFHHRKF';
Datetime now = DateTime.now();
Datetime expireson = now.addDays(2);
Long Lexpires = expireson.getTime()/1000;
String policyStatement = '{"Statement":[{"Resource":"jueh890044563.cloudfront.net/test.pdf","Condition":{"DateLessThan":{"AWS:EpochTime":'+Lexpires+'}}}]}';
policyStatement = EncodingUtil.base64Encode(Blob.valueOf(policyStatement));
String privateKey = 'dfgdfgtgdfgdfgdfsgdfgdfsgdfgdfgdfgsdf'+
'dfgdfgdfgdfgdfgdfgdfgdfgdfgfgdfgdfsdf'+
'dfdfgdfgdfgdfgdfgfdgdfg/i0AB1Jz20QlGy'+
'dsfgdfgdfgdfgdfgdfgdsfgdfgdfgffdfgdfg';
Blob mac = Crypto.generateMac('HmacSHA1', blob.valueof(policyStatement),blob.valueof(privateKey));
String signed = EncodingUtil.base64Encode(mac);
String downloadUrl = 'jueh890044563.cloudfront.net/test.pdf?Policy='+policyStatement+'&Signature='+signed+'&Key-Pair-Id='+keyPairId;
Is downloadUrl is singedUrl? When we run this url then return Access Denied.
Thanks in advance.
I am investigating the same. Have you been successful by now?
To separate SF domain from Amazon domain I would try to create the signed URL in UNIX shell or Java and compare the signatures. If they are the same then the problem is not on Salesforce side.
String keyPairId = 'AXXXXXXXXXXXXXXXXEFA';
String privateKey = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCds4huFsMlcqRJ'+
'InSvSsm1m3GoS4Lk/pBgN6hcU++ojh2iv00d9dQ0d3c1GMedNc+p3GvHas9IiWC1'+
'many more lines';
//this needs to come from a pkcs8 file
urlToSign = 'https://d3m1gol86ahpmn.cloudfront.net/sfroot/file.html;
policyStatementText = '{"Statement":[{"Resource":"' + urlToSign + '","Condition":{"DateLessThan":{"AWS:EpochTime":2000000000}}}]}';
String policyStatement = EncodingUtil.base64Encode(Blob.valueOf(policyStatementText ));
policyStatement = policyStatement .replace('+','-');
policyStatement = policyStatement .replace('=','_');
policyStatement = policyStatement .replace('/','~');
Blob mac = Crypto.sign('RSA-SHA1', blob.valueof(policyStatementText ),privateKeyBlob );
String signed = EncodingUtil.base64Encode(mac);
signed = signed.replace('+','-');
signed = signed.replace('=','_');
signed = signed.replace('/','~');
signedURL = urlToSign + '&Policy=' + policyStatement + '&Signature=' + signed + '&Key-Pair-Id=' + keyPairId ;