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

HttpRequest Callout to Azure Message Queue REST API
I'm trying to drop messages on an Azure message queue for processing. I have been able to build the HttpRequest, but am receiving a 403 - failed to authenticate message from Azure when calling the REST API. I am using the following code:
string storageKey = 'removedforprivacy'; Datetime dt = Datetime.now(); string formattedDate = dt.formatGMT('EEE, dd MMM yyyy HH:mm:ss') + ' UTC'; string stringToSign = 'POST\n\napplication/xml\n\nx-ms-date:' + formattedDate + '\n' + '/myqueue/testqueue/messages'; // Sign the request Blob temp = EncodingUtil.base64Decode(storageKey); Blob hmac = Crypto.generateMac('HMacSHA256', Blob.valueOf(stringToSign), temp); string signature = EncodingUtil.base64Encode(hmac); Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)))); // This ends up being the exact same as the console app system.debug('SIGNATURE==>SharedKey myqueue:' + signature); HttpRequest req = new HttpRequest(); req.setMethod('POST'); req.setHeader('content-type', 'application/xml'); req.setHeader('x-ms-date', formattedDate); string authHeader = 'SharedKey myqueue:' + signature; req.setHeader('Authorization', authHeader); req.setEndpoint('https://myqueue.queue.core.windows.net/testqueue/messages'); req.setBody('<QueueMessage><MessageText>' + EncodingUtil.base64Encode(Blob.valueOf('This is a test from salesforce')) + '</MessageText></QueueMessage>'); system.debug(req); Http http = new Http(); try { HTTPResponse res = http.send(req); system.debug(res.toString()); system.debug(res.getStatus()); system.debug(res.getStatusCode()); } catch (system.CalloutException ce) { system.debug(ce); }I created a small .NET console app to verify how to create the request and the connectivity. Once that was working, I verified the signed signature used in the Authorization header is the same when created both in .NET and in Salesforce. Has anyone else came across this? Is there something you can see in the code I have written? Is there a way for me to capture the HttpRequest that is being posted by Salesforce (something similar to fiddler would be great)?
All Answers
I'm trying something similar but for peeking a message. However, I'm getting an error signing the request. Your line #12: Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)))); is not ok. How do you manage to sign it ?
Thank you very much!
Hope it helps.
Thank you so much, I believe it will help many people!
First Of all I'll thank you for the solution you have provided for sending messages to Azure queue. I have also not exactly but very similar requirement, I have to fetch blobs from Azure Storage and I have follwed your path only but still I amm facing same issue that you're facing. I am stuck here from past few days. Can you please help me? Here is my code.
public class AzurePOC {
public void azurePOCMethod(){
string storageKey = 'Z7yhAnPUt8iYXSkMK3lvHqQEDS92kR2h5hbZWn6oAjTFrpcsDhEbobcuBxpVtTyHcCTZfds1UnrtUtIESMGJBQ==';
Datetime dt = Datetime.now().addMinutes(-5);
string formattedDate = dt.formatGMT('EEE, dd MMM yyyy HH:mm:ss z');
//string stringToSign = 'GET\n\napplication/xml\n\n\n' +'/testcontainer/2016';
//string stringToSign = 'GET\n\napplication/xml\n\nx-ms-date:' + formattedDate + '\n/testaccount5678/bill';
string stringToSign = 'GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:'+formattedDate+'\nx-ms-version:2009-09-19\n/testaccount5678/bill\ncomp:metadata\nrestype:container\ntimeout:20';
// Sign the request
Blob temp = EncodingUtil.base64Decode(storageKey);
Blob hmac = Crypto.generateMac('HMacSHA256', Blob.valueOf(stringToSign), temp);
string signature = EncodingUtil.base64Encode(hmac);
system.debug('SIGNATURE==>SharedKey :' + signature);
system.debug('formattedDate:'+formattedDate);
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setHeader('content-type', 'application/xml');
req.setHeader('x-ms-date', formattedDate);
string authHeader = 'SharedKey testaccount5678:' + signature;
req.setHeader('Authorization', authHeader);
req.setHeader('x-ms-version', '2009-09-19');
//req.setHeader('Content-Length', '0');
req.setEndpoint('https://testaccount5678.blob.core.windows.net/bill/test567');
system.debug(req);
Http http = new Http();
try
{
HTTPResponse res = http.send(req);
system.debug(res.toString());
system.debug(res.getStatus());
system.debug(res.getStatusCode());
}
catch (system.CalloutException ce)
{
system.debug(ce);
}
}
}
18:28:17.50 (645456782)|USER_DEBUG|[44]|DEBUG|System.HttpResponse[Status=Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature., StatusCode=403] 18:28:17.50 (645510084)|USER_DEBUG|[45]|DEBUG|Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. 18:28:17.50 (645545530)|USER_DEBUG|[46]|DEBUG|403
I am using exact same code posted above by Chad