Trying to generate an SAS Token to access certain files in a Storage Account. I'm using the methods listed here:
https://docs.microsoft.com/en-us/rest/api/eventhub/generate-sas-token
Now, the problem I have is I cannot, for the life of me, make the sasToken string work. If I generate the token via the Portal (Shared Access Signature in the Storage Account), I can access those files via a URL with the provided Token.
However I have yet to be able to generate an SAS token programmatically via Java using the methods I linked above. I think my problem is the StringToSign that is being encrypted. I've been following this example when constructing the string to encrypt:
https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas
All my efforts have resulted in either:
<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>
or
<AuthenticationErrorDetail>Signature did not match. String to sign used was <insert string details here>
Looking at the Portal generated sasToken that works for me:
?sv=2017-11-09&ss=f&srt=o&sp=r&se=2018-12-06T22:15:20Z&st=2018-12-06T14:15:20Z&spr=https&sig=%2Bi1TWv5D80U%2BoaIeoBh1wjaO1p4xVFx4nRZt%2FzwiszY%3D
It seems I need a String like so:
String stringToSign = accountName + "\n" +
"r\n" +
"f\n" +
"o\n" +
URLEncoder.encode(start, "UTF-8") + "\n" +
URLEncoder.encode(expiry, "UTF-8") + "\n" +
"\n" +
"https\n" +
azureApiVersion;
Where accountName is the storage account name from Azure, and start/expiry are the start and expiry strings (ie- 2018-12-06T22:15:20Z) and azureApiVersion is "2017-11-09".
I then try to return the token after constructing the string like so:
String signature = getHMAC256(key, stringToSign);
sasToken = "sv=" + azureApiVersion +
"&ss=f" +
"&srt=o" +
"&sp=r" +
"&se=" +URLEncoder.encode(expiry, "UTF-8") +
"&st=" + URLEncoder.encode(start, "UTF-8") +
"&spr=https" +
"&sig=" + URLEncoder.encode(signature, "UTF-8");
I've tried URL encoding and not URL encoding the the start/expiry dates as well, just in case that was messing things up. What am I missing?
getHMAC256
method. I looked up the code for it and it is simply getting the bytes from string value. Actually you would need to base64 decode the key string and use that byte array in this method. – Gaurav Mantri