You need to sign in to do that
Don't have an account?
John Issa
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!
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)