Forum Discussion
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
- jkrolczy5 years agoRegular 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?
- jkrolczy5 years agoRegular 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.BigIntegerSimpleDateFormat 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 hashAny 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.
- richie5 years agoCommunity Hero
Hey jkrolczy
Apologies - its been a couple of days since I checked the forum - so I missed your message with the x-ms-date timezone query.
The docs.microsoft.com/ site doesn't really discuss datetimes that are not UTC/GMT.
I checked and Austin Texas is GMT/UTC - 5 hours.
If it were XML I'd suggest following xml schema's xs:datetime (ISO8601) format of CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm (where Z indicates UTC and the timezone offset is plus/minus hh:mm
It's json however and json doesnt include a date type. However, javascripts date toJSON method and ISO8601 indicates json date should be "CCYY-MM-DDTHH:MM:SS-hh:mm" (same timezone offset approach as the XML - which is unsurprising considering they're both ISO8601 compliant), so I'm guessing "14 Jul 2020 04:04:00-05:00" is as good as any attempt.
You asked what's the +/- variation allowed. I wouldn't have expected there to be any, but I don't see that as a problem anyway. As long as you pick up the current date time (which I think you're doing in your code anyway) and then just concatenate the '-05:00' to the end - surely that's good enough for the x-ms-date header?
As you can tell - I'm guessing - but making educated guesses at least - the MS docs really bite for the lowest level of detail needed - it just doesn't define it (as I found when trying to setup my PUT request) - so it's lots of trial and error.
Sorry I can't be of further help!
Cheers,
Rich
Related Content
- 9 months ago
- 5 years ago
- 4 years ago