You need to sign in to do that
Don't have an account?

Connect to AWS S3 from APEX using AWS Signature Version 4r
String accessKey = 'ACCESSKEY'; String secretKey = 'SECRETKEY'; String bucketname = 'BUCKETNAME'; String host = 's3-us-west-1.amazonaws.com'; String filename = 'test1.json'; String hashAlgo = 'HmacSHA256'; String url = 'https://' + bucketname + '.' + host + '/' + filename; Date currentDate = date.today(); DateTime currentDateRaw = DateTime.now(); String currentDateOnly = DateTime.now().formatGMT('EEE, dd MMM yyyy HH:mm:ss z'); String regionName = 'us-west-1'; String serviceName = 's3'; String strBody = ''; //////////////////////////////////// // 1 - CANONICAL REQUEST //////////////////////////////////// String strCanonicalRequest = ''; strCanonicalRequest+='PUT\n'; strCanonicalRequest+='\n'; strCanonicalRequest+='content-type:application/x-www-form-urlencoded; charset=utf-8\n'; strCanonicalRequest+='host:s3-us-west-1.amazonaws.com\n'; strCanonicalRequest+='x-amz-date:' + currentDate + '\n'; strCanonicalRequest+='\n'; strCanonicalRequest+='content-type;host;x-amz-date'; String strPayloadHash = EncodingUtil.convertToHex(Crypto.generateDigest('SHA-256', Blob.valueOf(strBody))); // Payload strCanonicalRequest+= '\n' + strPayloadHash.toLowerCase(); //////////////////////////////////// // 2 - STRING TO SIGN //////////////////////////////////// String strStringToSign = ''; strStringToSign+='AWS4-HMAC-SHA256\n'; strStringToSign+=currentDateRaw + '\n'; strStringToSign+=currentDateOnly + '/' + regionName + '/' + serviceName + '/aws4_request'; String strCanonicalHash = EncodingUtil.convertToHex(Crypto.generateDigest('SHA-256', Blob.valueOf(strCanonicalRequest))); // Payload strStringToSign+= '\n' + strCanonicalHash.toLowerCase(); //////////////////////////////////// // 3 - SIGNATURE //////////////////////////////////// String kSecret = 'AWS4' + secretKey; Blob kDate = Crypto.generateMac(hashAlgo, Blob.valueOf(currentDateOnly), Blob.valueOf(kSecret)); Blob kRegion = Crypto.generateMac(hashAlgo, Blob.valueOf(regionName), kDate); Blob kService = Crypto.generateMac(hashAlgo, Blob.valueOf(serviceName), kRegion); Blob kSigning = Crypto.generateMac(hashAlgo, Blob.valueOf('aws4_request'), kService); String strSignature = EncodingUtil.convertToHex(Crypto.generateMac(hashAlgo, Blob.valueOf(strStringToSign), kSigning)); strSignature = strSignature.toLowerCase(); //////////////////////////////////// // 4 - AUTHORIZATION HEADER //////////////////////////////////// String strAuthorizationHeader = 'AWS4-HMAC-SHA256 '; strAuthorizationHeader+= 'Credential=' + accessKey + '/' + currentDateOnly + '/' + regionName + '/' + serviceName + '/aws4_request, '; strAuthorizationHeader+= 'SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, '; strAuthorizationHeader+= 'Signature=' + strSignature; // PUT Http http = new Http(); HttpRequest req = new HttpRequest(); req.setEndPoint(url); req.setMethod('PUT'); req.setBody(body); req.setHeader('ACL', 'public-read-write'); req.setHeader('Authorization', strAuthorizationHeader); req.setHeader('Date', currentDateOnly); req.setHeader('x-amz-content-sha256', 'UNSIGNED-PAYLOAD'); HttpResponse response = http.send(req); if (response.getStatusCode() != 200) { System.debug('The status code returned was not expected: ' + response.getStatusCode() + ' ' + response.getStatus()); System.debug('Auth: ' + strAuthorizationHeader); else { Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody()); System.debug('This is working'); System.debug(response.getBody()); String output = (String)results.get('result'); }
Hello,
I'm in the process of connecting to S3 out of APEX and I'm receiving the following error message when executing an anonymous request:
The authorization header is malformed; the authorization header requires three components: Credential, SignedHeaders, and Signature.
Example of Signature:
Auth: AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/Tue, 09 Jul 2019 07:54:14 GMT/us-west-1/s3/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=fe5f80f77d5fa3beca038a248ff027d04453421fe2855ddc963176630326f1024
When I look at the authorization signature, it looks to be setup correctly. I"m able to add that signature to the body of my postman request and I get a successful response but when I add it as a header, I receive a 403 message.
Has any one experienced something similar? If so, any assistance woiuld be greatly appreciated. TY!
Here's a gist that shows the basic framework that I developed. To actually implement a sub-service using this framework, you simply need a couple of extra steps, outlined here:
Regards - AWS Training in pune (https://writeupcafe.com/community/new-terminologies-in-aws/?snax_post_submission=success)