azure REST API communication

383 Views Asked by At

I'm currently trying retrieve list share available in my Azure account from salesforce. I'm trying to implement the example from below sample code:

https://learn.microsoft.com/en-us/rest/api/storageservices/list-shares#samplerequestandresponse

    //private key: access key of my account
   string storageKey =private key;
        string storageName = 'accountName';
        Datetime dt = Datetime.now();
        string formattedDate = dt.formatGMT('EEE, dd MMM yyyy HH:mm:ss')+ ' GMT';
        system.debug('formattedDate--'+formattedDate);

        string CanonicalizedHeaders = 'x-ms-date:'+formattedDate+'\nx-ms-version:2016-05-31';
        string CanonicalizedResource = '/' + storageName + '/\ncomp:list';
        string StringToSign = 'GET\n\n\n\n\n\n\n\n\n\n\n\n' + CanonicalizedHeaders+'\n'+CanonicalizedResource;
        system.debug('StringToSign--'+StringToSign);

        Blob temp = EncodingUtil.base64Decode(storageKey);
        Blob hmac = Crypto.generateMac('HmacSHA256',Blob.valueOf(StringToSign),temp ); //StringToSign
        system.debug('oo-'+EncodingUtil.base64Encode(hmac));
        HttpRequest req = new HttpRequest();
        req.setMethod('GET');
        //req.setHeader('content-type', 'application/xml');
        req.setHeader('x-ms-version','2016-05-31' );
        req.setHeader('x-ms-date', formattedDate);
        string signature = EncodingUtil.base64Encode(hmac);
        string authHeader =  'SharedKey salesforcestrongaccount'+':'+signature;

        req.setHeader('Authorization',authHeader);
        req.setEndpoint('https://<accountName>.file.core.windows.net/?comp=list');

        Http http = new Http();
        HTTPResponse res;
        res = http.send(req);                
        System.debug(LoggingLevel.INFO, 'http.send result status: ' + res.getStatus());

Any help?

1

There are 1 best solutions below

5
On

As Gaurav Mantri says, there are something wrong with your stringToSign. So you will get this error.

The right Shared Key Authentication is like this:

StringToSign = VERB + "\n" +  
               Content-Encoding + "\n" +  
               Content-Language + "\n" +  
               Content-Length + "\n" +  
               Content-MD5 + "\n" +  
               Content-Type + "\n" +  
               Date + "\n" +  
               If-Modified-Since + "\n" +  
               If-Match + "\n" +  
               If-None-Match + "\n" +  
               If-Unmodified-Since + "\n" +  
               Range + "\n" +  
               CanonicalizedHeaders +   
               CanonicalizedResource; 

Here I create a test demo, you could refer to it.

List share:

        string storageAccount = "storage account";
        string accessKey = "accountkey";
        string resourcePath = "?comp=list";
        string uri = @"https://" + storageAccount + ".file.core.windows.net/" + resourcePath;
        // Web request 
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
        request.Method = "GET";
        request.Headers["x-ms-date"] = DateTime.UtcNow.ToString("R", System.Globalization.CultureInfo.InvariantCulture);
        request.Headers["x-ms-version"] = "2015-02-21";
        String stringToSign = "GET\n"
            + "\n" // content encoding
            + "\n" // content language
            + "\n" // content length
            + "\n" // content md5
            + "\n" // content type
            + "\n" // date
            + "\n" // if modified since
            + "\n" // if match
            + "\n" // if none match
            + "\n" // if unmodified since
            + "\n" // range
            + "x-ms-date:" + request.Headers["x-ms-date"] + "\nx-ms-version:2015-02-21\n" // headers
            + "/" + storageAccount + "/" + "\ncomp:list"; // resources

        System.Security.Cryptography.HMACSHA256 hasher = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(accessKey));
        string strAuthorization = "SharedKey " + storageAccount + ":" + System.Convert.ToBase64String(hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringToSign)));


        request.Headers["Authorization"] = strAuthorization;

        Task<WebResponse> response = request.GetResponseAsync();
        HttpWebResponse responseresult = (HttpWebResponse)response.Result;

        using (System.IO.StreamReader r = new System.IO.StreamReader(responseresult.GetResponseStream()))
        {
            string jsonData = r.ReadToEnd();
            Console.WriteLine(jsonData);
        }

Result:

enter image description here

Java:

private static final String account = "accountname";
    private static final String key = "Key";

    public static void main(String args[]) throws Exception {
//      String urlString = "http://" + account + ".file.core.windows.net/sampleshare/name.txt";
        String urlString = "https://" + account + ".file.core.windows.net/?comp=list";
        HttpURLConnection connection = (HttpURLConnection) (new URL(urlString)).openConnection();
        getFileRequest(connection, account, key);
        connection.connect();
        System.out.println("Response message : " + connection.getResponseMessage());
        System.out.println("Response code : " + connection.getResponseCode());

        BufferedReader br = null;
        if (connection.getResponseCode() != 200) {
            br = new BufferedReader(new InputStreamReader((connection.getErrorStream())));
        } else {
            br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
        }
        System.out.println("Response body : " + br.readLine());
    }

    public static void getFileRequest(HttpURLConnection request, String account, String key) throws Exception {
        SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
        fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = fmt.format(Calendar.getInstance().getTime()) + " GMT";
        String stringToSign = "GET\n" + "\n" // content encoding
                + "\n" // content language
                + "\n" // content length
                + "\n" // content md5
                + "\n" // content type
                + "\n" // date
                + "\n" // if modified since
                + "\n" // if match
                + "\n" // if none match
                + "\n" // if unmodified since
                + "\n" // range
                + "x-ms-date:" + date + "\nx-ms-version:2015-02-21\n" // headers
                + "/" + account + request.getURL().getPath() + "\ncomp:list"; // resources
        System.out.println("stringToSign : " + stringToSign);
        String auth = getAuthenticationString(stringToSign);
        request.setRequestMethod("GET");
        request.setRequestProperty("x-ms-date", date);
        request.setRequestProperty("x-ms-version", "2015-02-21");
        request.setRequestProperty("Authorization", auth);
    }

    private static String getAuthenticationString(String stringToSign) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(Base64.decode(key), "HmacSHA256"));
        String authKey = new String(Base64.encode(mac.doFinal(stringToSign.getBytes("UTF-8"))));
        String auth = "SharedKey " + account + ":" + authKey;
        return auth;
    }