Forum Discussion

jkrolczy's avatar
jkrolczy
Regular Contributor
4 years ago

SoapUI: GET REST: Request Header Example for Azure File service REST API

Using SoapUI O S - 5.5.0

 

I have been trying to figure out how to work with the Azure REST API lately

and I am probably making this harder than it should be.

I am not making any progress with. ☹️

 

https://docs.microsoft.com/en-us/rest/api/storageservices/file-service-rest-api  

 

I am looking for a working example/suggestions on how to setup a simple GET REST request for :

 

List Shares

https://docs.microsoft.com/en-us/rest/api/storageservices/list-shares 

 

The Request Header for the required info is what I have not figured out how to set correctly.

If I can get this sorted out and get the GET request to work, I can proceed in my testing goal.

 

Request Headers

The following table describes required and optional request headers.

Request HeadersRequest Header Description
AuthorizationRequired. Specifies the authorization scheme, account name, and signature. For more information, see Authorize requests to Azure Storage.
Date or x-ms-dateRequired. Specifies the Coordinated Universal Time (UTC) for the request. For more information, see Authorize requests to Azure Storage.
x-ms-versionRequired for all authorized requests. Specifies the version of the operation to use for this request. For more information, see Versioning for the Azure Storage Services.

 

For the Authorization part I am using a Shared Key (storage account key) since that 

is supported for all the Storage Services which is my bigger goal in accessing for service testing

and verification.

 

I look forward for any help suggestions.

Thanks

 

4 Replies

  • richie's avatar
    richie
    Community Hero

    Hey jkrolczy 

     

    About 2 years ago - I had to setup a PUT request to publish a file to Azure BLOB storage (rather than a GET to query Azure storage).  I spent about 4 days to try and work out the different query and header parameters (in the end there were eleven header and query parms) that are required and it was a complete nightmare cos there's so much conflicting stuff on the web and Azure storage has changed so much over the different versions.

     

    My request was as follows:
    
    PUT https://XXXXXppermissions.blob.core.windows.net/permissionupdates/TestCase1_01-07-2020.csv?sv=2017-11-09&ss=b&srt=sco&sp=rwdlac&se=2018-12-31T22:05:57Z&st=2018-09-12T13:05:57Z&spr=https&sig=aSusvcLmoB+sJeRKUfW69pEPOPfVp/iBJ01gQGBDQwA=

     

    Anyway

     

    The instructions indicate the request URL is as follows:

     

    https://myaccount.file.core.windows.net/?comp=list

     

    From the instructions available via https://docs.microsoft.com/en-us/rest/api/storageservices/,  as well as https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-requests-to-azure-storage, and https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key and https://docs.microsoft.com/en-us/rest/api/storageservices/versioning-for-the-azure-storage-services

     

    I think you need 3 headers in your GET request:

    Authorization, x-ms-version & x-ms-date

     

    The format for Shared Key Authorization header is as follows:

    Authorization="[SharedKey|SharedKeyLite] <AccountName>:<Signature>"

     

    so it should read something like

    Authorization="SharedKey accountname:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=

     

    SharedKey is the name of the authorization scheme, AccountName is the name of the account requesting the resource, and Signature is a Hash-based Message Authentication Code (HMAC) constructed from the request and computed by using the SHA256 algorithm, and then encoded by using Base64 encoding

     

    x-ms-version is typically in the format of '2017-11-09'  (yes I know it looks like a date rather than a version number - I think a while ago they used to use values like 1.0 - but sometimes in the last 4 or 5years this changed.)

     

    x-ms-date is typically in the format of 'Fri, 26 Jun 2015 23:39:12 GMT'

     

    If this doesn't help, please hit me back - I dont have access to my Azure BLOB storage endpoint anymore so trial and error is out - but I might be able to help further if I know the error response generated if this doesn't work

     

    Cheers,

     

    Rich

    • jkrolczy's avatar
      jkrolczy
      Regular Contributor

       

      Thanks for the reply back.

       

      Glad to see I am not the only one who has issues trying to decipher Microsoft's Azure REST API reference information.

       

      I still have to play with this more from what you sent me.

      I am on the right path per what you mentioned.

       

      I re-verify the Authorization format as well as the Version used for x-ms-version.

       

      The x-ms-date part is where I am confused because I cannot determine by what timezone location

      on Earth I should be using here.  I live in Texas, so for x-ms-date, if I sent a GET request right now,

      is this per my timezone or per Greenwich England ?  And what is the fudge factor here for it to be accurate

      when being set and sent?

       

       

      • jkrolczy's avatar
        jkrolczy
        Regular Contributor

        Following back up on this, since I got to play with some more:

         

        The format for Shared Key Authorization header is as follows:

        Authorization="[SharedKey|SharedKeyLite] <AccountName>:<Signature>"

         

        so it should read something like

        Authorization="SharedKey accountname:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=

         

        SharedKey is the name of the authorization scheme, AccountName is the name of the account requesting the resource, and Signature is a Hash-based Message Authentication Code (HMAC) constructed from the request and computed by using the SHA256 algorithm, and then encoded by using Base64 encoding

         

        I put together some Groovy script code, to try to do the above encoding:

        The code is not correct yet but a start to which I am turning to debug and

        fine tune to encode correctly per the above mentioned paragraph.

         

        import java.text.SimpleDateFormat;
        import javax.crypto.Mac;
        import javax.crypto.spec.SecretKeySpec;
        import java.security.InvalidKeyException;
        import java.math.BigInteger

         

        SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = sdf.format(new Date()) + " GMT";


        //signature = signature + "\nx-ms-date:" + date;

        log.info "\nx-ms-date:" + date;

         

        /**
        * Param secretKey
        * Param data
        * @return HMAC/SHA256 representation of the given string
        */
        //def hmac_sha256(String secretKey, String data)


        def key = "<Shared Key from Azure account>==";   // Does not have signature part added to it yet
        log.info key;
        //def strTime = (new Date()).toUTCString();
        def strTime = date;
        log.info strTime;

        def strToSign = 'GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:' + strTime + '\nx-ms-version:2017-11-09\n/nprodpayconm3repo/\ncomp:list';
        log.info strToSign;

        //def secret = CryptoJS.enc.Base64.parse(key);
        def secret = key.bytes.encodeBase64().toString();
        log.info secret;

        def secretKey = "<Shared Key from Azure account>==";
        log.info secretKey;

        def data = key.bytes.encodeBase64().toString();
        log.info data;

        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256")
        Mac mac = Mac.getInstance("HmacSHA256")
        mac.init(secretKeySpec)
        byte[] digest = mac.doFinal(data.getBytes("UTF-8"))

        BigInteger bigInteger = new BigInteger(1, digest)
        String hash = bigInteger.toString(16)
        //Zero pad it
        while (hash.length() < 64)
        {
        hash = "0" + hash
        }

        log.info "-----------"
        log.info "HASH:"
        log.info hash

         

        Any more suggestion from the community for my issue would be much appreciated.

        There has to be other folks out there accessing Azure using it's REST APIs.