0
String dateStamp = EncodingUtil.urlEncode( System.now().formatGmt('yyyyMMdd'), 'UTF-8');
System.debug('dateStamp>>' + dateStamp);
String dateTimeStamp = EncodingUtil.urlEncode(System.now().formatGmt('yyyyMMdd') + 'T' + System.now().formatGmt('HHmmss') + 'Z', 'UTF-8');
System.debug('dateTimeStamp>>' + dateTimeStamp);

String url = 'https://awis.api.alexa.com/api?';

String algorithm = 'AWS4-HMAC-SHA256';
String credentialScope = dateStamp + '/us-east-1/execute-api/aws4_request';
String canonicalQuery = 'Action=UrlInfo&ResponseGroup=' + EncodingUtil.urlEncode('Rank', 'UTF-8') 
                                + '&Url=' + EncodingUtil.urlEncode(urlToQuery, 'UTF-8') ;

String canonicalHeaders = 'host:awis.api.alexa.com\nx-amz-date:' + dateTimeStamp; 
String signedHeaders = 'host;x-amz-date';

String payloadHash = EncodingUtil.convertToHex(Crypto.generateDigest('sha256', Blob.valueOf('')));

String canonicalRequest = 'GET\n' + '/api' + '\n' + canonicalQuery + '\n' + canonicalHeaders  +'\n' + signedHeaders + '\n' + payloadHash;
//EncodingUtil.converttohex
String stringToSign = algorithm + '\n' +  dateTimeStamp + '\n' +  credentialScope + '\n' +  EncodingUtil.base64Encode(Crypto.generateDigest('sha256',Blob.valueOf(canonicalRequest)));



Blob signingKey = Crypto.generateMac('hmacSHA256', Blob.valueOf('aws4_request'),
    Crypto.generateMac('hmacSHA256', Blob.valueOf('execute-api'),
        Crypto.generateMac('hmacSHA256', Blob.valueOf('us-east-1'),
            Crypto.generateMac('hmacSHA256', Blob.valueOf(dateStamp), Blob.valueOf('AWS4' + alexaSettings.SecretAccessKey__c))
        )
    )
);
//EncodingUtil.convertToHex(
String signature = EncodingUtil.convertToHex(Crypto.generateMac('hmacSHA256', Blob.valueOf(stringToSign), signingKey));
System.debug('signature:::' + signature);

String authorizationHeader = algorithm + ' ' + 'Credential=' + EncodingUtil.urlEncode(alexaSettings.AWSAccessKeyId__c, 'UTF-8') + '/' + credentialScope + ', ' +  'SignedHeaders=host;x-amz-date, ' + 'Signature=' + signature;

url = url + canonicalQuery;

System.debug('The URL is: ' + url);

HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Http http = new Http();
req.setEndpoint(url);
req.setHeader('Accept','application/xml');
req.setHeader('Content-Type', 'application/xml');

req.setHeader('X-Amz-Date', dateTimeStamp);


req.setHeader('Authorization',authorizationHeader);

req.setMethod('GET');
req.setTimeout(10000);                                   
res = http.send(req);

I am trying to get website rank using Alexa Web Information Service. But I am getting this error -

The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

Can anybody help me in knowing the flaws I'm having inside my code.

  • The error message seems remarkably clear here. You should take the advice in the error message and consult the AWIS documentation. – Derek F May 15 at 12:58
  • @DerekF I went thru with documentation and checked the steps to create signature, but that was not helpful to me. – Mukesh Saxena May 15 at 13:17
  • If you wait a few weeks for Summer '19 to hit, you can have AWS signature V4 support out of the box via Named Credentials: releasenotes.docs.salesforce.com/en-us/summer19/release-notes/… – identigral May 15 at 19:27

Your Answer

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

Browse other questions tagged or ask your own question.