none
Connecting to Message Queue from Salesforce through the REST API

    Question

  • I am working on creating a worker role that pulls items from the message queue to do processing.  The message queue is filled by multiple applications, one of which is Salesforce.  I seem to be having an issue with calling the REST API from Salesforce as I continue to get the 403 - Server failed to authenticate the request.  I have successfully connected through the REST API with a simple console app to verify connectivity and settings.  I have also verified that the code that creates the signed signature creates the same value in both Salesforce and in the .NET console app.  Unfortunately I can't seem to find a way to capture the HTTP request that Salesforce is sending.  Any ideas on what be happening or where things might be going wrong?  

    I am including the code from a Salesforce anonymous block for your viewing pleasure.  

    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);
    
        // 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);
        }


    • Edited by Chad VanHorn Wednesday, October 8, 2014 9:28 PM remove unnecessary commented out code
    Tuesday, October 7, 2014 10:24 PM

Answers

  • Finally figured out the issue after building the HTTP request manually outside of the Salesforce platform.  I apparently missed in the documentation that the datetime needs to be in GMT not UTC.  Switching that allows the code to drop messages on the queue as expected.
    • Marked as answer by Chad VanHorn Wednesday, October 8, 2014 8:28 PM
    Wednesday, October 8, 2014 8:28 PM

All replies

  • hi Chad,

    From this page(http://msdn.microsoft.com/en-US/library/azure/dn140255.aspx), I think your SAS token has some thing wrong. I recommend you refer to Gaurav's blog from this page( http://gauravmantri.com/2013/02/13/revisiting-windows-azure-shared-access-signature/ ).

    You can try to change blob storage to queue storage.

    Regards,

    Will


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, October 8, 2014 11:31 AM
    Moderator
  • Thanks for the reply, I appreciate you  looking at this.

    I am actually not using the SAS token as I am comfortable using the storage access key for this 'internal' application. I am trying to use the authentication header and the signed key (MSDN Article).  

    Wednesday, October 8, 2014 2:58 PM
  • Finally figured out the issue after building the HTTP request manually outside of the Salesforce platform.  I apparently missed in the documentation that the datetime needs to be in GMT not UTC.  Switching that allows the code to drop messages on the queue as expected.
    • Marked as answer by Chad VanHorn Wednesday, October 8, 2014 8:28 PM
    Wednesday, October 8, 2014 8:28 PM