I am using below mentioned snapshot rest api from MS
https://myaccount.blob.core.windows.net/mycontainer/myblob?comp=snapshot
https://docs.microsoft.com/en-us/rest/api/storageservices/snapshot-blob
Authorization Shared key which i generated is working perfect for all other operations which is having GET REST API Calls such as GetBlob,ListContainer,ListBlob.
I think for POST Call i am getting error but the logic is same for generating authorization shared key.
Cannonical Resource /storageaccountname/containername/8447a36f-43a3-4927-a23f-b8839f4c55e3DataDisk.vhd comp:snapshot
Cannonical Headers : x-ms-date:Thu, 18 May 2017 09:42:05 GMT x-ms-version:2014-02-14
Getting below mentioned error :
AuthenticationFailed
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:70447bc6-0001-0043-4271-d05281000000 Time:2017-05-19T07:27:25.2321062Z
The MAC signature found in the HTTP request '7FfeYCQ4SUfWH5OH1DLG7Qx1ZRceffesdDwmGKQWZYo=' is not the same as any computed signature. Server used following string to sign: 'PUT 0 x-ms-date:Fri, 19 May 2017 07:26:46 GMT x-ms-version:2014-02-14 /cscagilitysouthcentralus/vhds/8447a36f-43a3-4927-a23f-b8839f4c55e3AgilityDataDisk.vhd comp:snapshot'.
Let me know in headers i need to set any other mandatory parameters such as content lenght,content type,etc.,
Headers : Authorization : SharedKey storgeaccountname:gHYtJ5uOEQNztcdTpqAr3E20cARyFnrV8b3zuDpO9uk=
x-ms-version : 2014-02-14 x-ms-date : Wed, 17 May 2017 10:01:47 GMT
Java Code for generating Authorization SharedKey directly we can create class and copy paste this code :
public static void main(String... arg) throws URISyntaxException, Exception{
Map<String, String> requestHeaders = new HashMap<>();
requestHeaders.put("x-ms-version", "2014-02-14");
requestHeaders.put("x-ms-date", getStorageDate());
getAuthorizationHeader("PUT","storageaccount","storagekey",new URI("https://storageaccount.blob.core.windows.net/vhds/8447a36f-43a3-4927-a23f-b8839f4c55e3.vhd?comp=snapshot"),requestHeaders);
}
public static String getStorageDate()
{
Date d = new Date(System.currentTimeMillis());
SimpleDateFormat f = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
f.setTimeZone(TimeZone.getTimeZone("GMT"));
String dateString = f.format(d);
return dateString;
}
public static String getAuthorizationHeader(String verb, String storageAccount, String storageKey, URI resourceURI,
Map<String, String> requestHeaders) throws Exception
{
String authorizationStringToHash = getAuthorizationStringToHash(verb, storageAccount, requestHeaders, resourceURI);
String authorizationHash = hashString(storageKey, authorizationStringToHash);
System.out.println("StorageAccoutName::" + storageAccount);
System.out.println("Storage Key::" + storageKey);
System.out.println("authorizationStringToHash::" + authorizationStringToHash);
System.out.println("authorizationHash:: " + authorizationHash);
/* System.out.println(HttpClientFactory.getInstance()
.createHeader("Authorization", "SharedKey " + storageAccount + ":" + authorizationHash).getValue());*/
System.out.println("Authorization SharedKey " + storageAccount + ":" + authorizationHash);
return "";
}
public static String getAuthorizationStringToHash(String verb, String storageAccount, Map<String, String> headers,
URI resourceURI) throws Exception
{
Map<String, String> headersToCanonicalize = new HashMap<String, String>();
String contentEncoding = "";
String contentLanguage = "";
String contentLength = "";
String contentMD5 = "";
String contentType = "";
String date = "";
String ifModifiedSince = "";
String ifMatch = "";
String ifNoneMatch = "";
String ifUnModifiedSince = "";
String range = "";
Set<String> keySet = headers.keySet();
for (String header : keySet)
{
if ("content-encoding".equals(header))
{
contentEncoding = headers.get(header);
}
else if ("content-language".equals(header))
{
contentLanguage = headers.get(header);
}
else if ("content-length".equals(header))
{
contentLength = headers.get(header);
}
else if ("content-md5".equals(header))
{
contentType = headers.get(header);
}
else if ("content-type".equals(header))
{
contentType = headers.get(header);
}
else if ("date".equals(header))
{
date = "";
}
else if ("if-modified-since".equals(header))
{
ifModifiedSince =headers.get(header);
}
else if ("if-match".equals(header))
{
ifMatch = headers.get(header);
}
else if ("if-none-match".equals(header))
{
ifNoneMatch =headers.get(header);
}
else if ("if-unmodified-since".equals(header))
{
ifUnModifiedSince =headers.get(header);
}
else if ("range".equals(header))
{
range = headers.get(header);
}
else
{
headersToCanonicalize.put(header, headers.get(header));
}
}
StringBuffer hashBuffer = new StringBuffer(verb);
hashBuffer.append("\n");
hashBuffer.append(contentEncoding);
hashBuffer.append("\n");
hashBuffer.append(contentLanguage);
hashBuffer.append("\n");
hashBuffer.append(contentLength);
hashBuffer.append("\n");
hashBuffer.append(contentMD5);
hashBuffer.append("\n");
hashBuffer.append(contentType);
hashBuffer.append("\n");
hashBuffer.append(date);
hashBuffer.append("\n");
hashBuffer.append(ifModifiedSince);
hashBuffer.append("\n");
hashBuffer.append(ifMatch);
hashBuffer.append("\n");
hashBuffer.append(ifNoneMatch);
hashBuffer.append("\n");
hashBuffer.append(ifUnModifiedSince);
hashBuffer.append("\n");
hashBuffer.append(range);
hashBuffer.append("\n");
List<String> headerNames = new ArrayList<String>(headersToCanonicalize.keySet());
Collections.sort(headerNames);
for (String headerName : headerNames)
{
hashBuffer.append(canonicalizeHeader(headerName,headersToCanonicalize.get(headerName)));
hashBuffer.append("\n");
}
hashBuffer.append(canonicalizeResource(storageAccount, resourceURI.getPath(), resourceURI.getQuery()));
return hashBuffer.toString();
}
public static String hashString(String key, String stringToHash) throws Exception
{
byte[] keyBytes = DatatypeConverter.parseBase64Binary(key);
SecretKey myKey = new SecretKeySpec(keyBytes, "HMACSHA256");
Mac mac = Mac.getInstance("HMACSHA256");
mac.init(myKey);
byte[] stringUTF8Bytes = stringToHash.getBytes("UTF-8");
byte[] macBytes = mac.doFinal(stringUTF8Bytes);
return DatatypeConverter.printBase64Binary(macBytes);
}
public static String canonicalizeHeader(String headerName,String headervalue)
{
return headerName + ":" + headervalue;
}
// uri must not start with /
public static String canonicalizeResource(String account, String resourcePath, String query)
{
StringBuffer canonicalResourceBuffer = new StringBuffer("/");
canonicalResourceBuffer.append(account);
canonicalResourceBuffer.append(resourcePath);
List<String> sortedQueryParams = getOrderedQueryParams(query);
for (String queryParam : sortedQueryParams)
{
canonicalResourceBuffer.append("\n");
canonicalResourceBuffer.append(queryParam);
}
System.out.println("Cannonical Resource "+canonicalResourceBuffer.toString());
return canonicalResourceBuffer.toString();
}
public static List<String> getOrderedQueryParams(String queryParamsString)
{
Map<String, String> queryParams = new HashMap<String, String>();
if ((queryParamsString == null) || (queryParamsString.isEmpty()))
{
return Collections.EMPTY_LIST;
}
String[] queryParamsArray = queryParamsString.split("&");
if ((queryParamsArray == null) || (queryParamsArray.length == 0))
{
return Collections.EMPTY_LIST;
}
Arrays.sort(queryParamsArray);
for (String queryParam : queryParamsArray)
{
queryParam = queryParam.trim();
queryParam = queryParam.replaceFirst("[ \t]*=[ \t]*", "=");
String[] parts = queryParam.split("=");
if (parts.length == 2)
{
String key = parts[0];
String value = parts[1];
String currentValue = queryParams.get(key);
if (currentValue == null)
{
queryParams.put(key, value);
}
else
{
queryParams.put(key, currentValue + "," + value);
}
}
}
List<String> names = new ArrayList(queryParams.keySet());
Collections.sort(names);
List<String> sortedCanonicalQueryParams = new ArrayList<String>();
for (String name : names)
{
sortedCanonicalQueryParams.add(name + ":" + queryParams.get(name));
}
return sortedCanonicalQueryParams;
}