0
votes

I'm using Azure REST API to get Storage Blob Size Details using java, I got response "Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature"

    public static void getContainer() throws Exception {
            // Account info
            String accountName = "StorageName";
            String accountKey = "StorageKey";

            // Request Uri and Method
            String containerName = "ContainerName";
            String requestUri = "https://" + accountName + ".blob.core.windows.net/" + containerName + "?restype=container&comp=metadata";
            System.out.println("requestUri = " + requestUri);
            HttpURLConnection connection = (HttpURLConnection) (new URL(requestUri)).openConnection();
            connection.setRequestMethod("GET");

            // Request Headers
            // 1. x-ms-version, recommend to use the latest version if possible
            String serviceVersion = "2018-03-28";
            // 2. x-ms-date
            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 authKeyFormat = "SharedKey";
            String caHeader = "x-ms-date:" + date + "\nx-ms-version:" + serviceVersion + "\n";
            String caResource = "/" + accountName + "/" + containerName + "ncomp:metadata\\nrestype:container";
            String signStr = "GET\n\n\n\n\n\n\n\n\n\n\n" + caHeader + caResource;
            System.out.println("signStr = " + signStr);
            String authorization = getAuthorization(accountName, authKeyFormat, signStr, accountKey);
            System.out.println("x-ms-version = " + serviceVersion);
            System.out.println("x-ms-date = " + date);
            System.out.println("Authorization = " + authorization);
            connection.setRequestProperty("x-ms-version", serviceVersion);
            connection.setRequestProperty("x-ms-date", date);
            connection.setRequestProperty("Authorization", authorization);
            connection.setDoOutput(true);
            connection.setFixedLengthStreamingMode(0);

            System.out.println("Response message : " + connection.getResponseMessage());
            System.out.println("Response code : " + connection.getResponseCode());
        }

        private static String getAuthorization(String accountName, String authKeyFormat, String signStr, String accountKey) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException, java.security.InvalidKeyException, Base64DecodingException {
            SecretKeySpec secretKey = new SecretKeySpec(Base64.decode(accountKey), "HmacSHA256");
            Mac sha256HMAC = Mac.getInstance("HmacSHA256");
            sha256HMAC.init(secretKey);
            String signature = Base64.encode(sha256HMAC.doFinal(signStr.getBytes("UTF8")));
            return authKeyFormat + " " + accountName + ":" + signature;
        }

Storage request and response detail

  GET -  https://StorageName.blob.core.windows.net/ContainerName?restype=container&comp=metadata   
    x-ms-version = 2018-03-28
    x-ms-date = Tue, 18 Jun 2019 13:46:41 GMT
    Authorization = SharedKey StorageName:Pp8E/FAxeIHDYs17r2GRYvL8xAgJ/D5eJuqlVW3+aiU=

Response message : Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. Response code : 403

we aren't able to authenticate the storage Account, hence we are not able to get the blob content size

1
which version of azure-storage-blob you are using?dassum
Why don't you use Azure Storage SDK for Java? azure.microsoft.com/en-us/resources/samples/…Peter Pan

1 Answers

0
votes

I would suggest you to use Java sdk for Azure storage as it gives the flexibility and more option. By using SDK you can simply use BlobProperties for getting the size.

You can refer below document:

https://azure.github.io/azure-sdk-for-java/com/microsoft/azure/storage/blob/BlobProperties.html#getLength--

If you are still planning to use the rest api then i would suggest you to look at the below api:

https://myaccount.blob.core.windows.net/mycontainer/myblob

The **Get Blob** Properties operation returns all user-defined metadata, standard HTTP properties, and system properties for the blob. It does not return the content of the blob

Here is the sample response, Content-Length : is the tag you might be interested in as it gives the overall size in bytes.

Response Status:  
HTTP/1.1 200 OK  

Response Headers:  
x-ms-meta-Name: myblob.txt  
x-ms-meta-DateUploaded: <date>  
x-ms-blob-type: AppendBlob  
x-ms-lease-status: unlocked  
x-ms-lease-state: available  
Content-Length: 11  
Content-Type: text/plain; charset=UTF-8  
Date: <date>  
ETag: "0x8CAE97120C1FF22"  
Accept-Ranges: bytes  
x-ms-blob-committed–block-count: 1  
x-ms-version: 2015-02-21  
Last-Modified: <date>  
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0  
x-ms-copy-id: 36650d67-05c9-4a24-9a7d-a2213e53caf6  
x-ms-copy-source: <url>  
x-ms-copy-status: success  
x-ms-copy-progress: 11/11  
x-ms-copy-completion-time: <date>  

Hope it helps.

https://docs.microsoft.com/en-us/rest/api/storageservices/get-blob-properties