Issue while downloading blob document using account SAS with Azure Java SDK

Pramit Bhaumik 1 Reputation point
2020-10-01T21:21:27.817+00:00

Hello ,

I am trying to download a blob file using account SAS .

I have written following method to generate SAS token

 public static String getAccountSAS(String accountName, String accountKey, String endpoint, String startTime,
 String endTime, String apiVersion) throws UnsupportedEncodingException {

String stringToSign = accountName + "\n" + "r\n" + "b\n" + "sco\n" + startTime + "\n" + endTime + "\n" + "\n"
            + "https\n" + apiVersion + "\n";

    String signature = getHMAC256(accountKey, stringToSign);

    String sasToken = "sv=" + apiVersion + "&ss=b" + "&srt=sco" + "&sp=r" + "&st="
            + URLEncoder.encode(startTime, "UTF-8") + "&se=" + URLEncoder.encode(endTime, "UTF-8") + "&spr=https"
            + "&sig=" + URLEncoder.encode(signature, "UTF-8");


    return sasToken;
 }

 private static String getHMAC256(String accountKey, String signStr) {
 String signature = null;
 try {
 SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(accountKey), "HmacSHA256");
 Mac sha256HMAC = Mac.getInstance("HmacSHA256");
 sha256HMAC.init(secretKey);
 signature = Base64.getEncoder().encodeToString(sha256HMAC.doFinal(signStr.getBytes("UTF-8")));
 } catch (Exception e) {
 e.printStackTrace();
 }
 return signature;
 }

Allow below is the code to generate Blob Container client and download the file -

 String sasToken = getAccountSAS(mapString.get("accountName"), mapString.get("accessKey"),
 mapString.get("endpoint"), mapString.get("startTime"), mapString.get("endTime"),
 mapString.get("apiversion"));




  BlobServiceClient storageClient = new
   BlobServiceClientBuilder().endpoint(mapString.get("endpoint"))
   .sasToken(sasToken)
   .buildClient();

 BlobContainerClient blobContainerClient = storageClient.getBlobContainerClient("demo");

 blobContainerClient.listBlobs().forEach(blobItem -> {
 System.out.println("Item Name" + blobItem.getName());
 BlobClient blobClient = blobContainerClient.getBlobClient(blobItem.getName());
 blobClient.downloadToFile(
blobItem.getName().replace("/", "-"));

 });

But the program is giving following exception -

Exception in thread "main" com.azure.storage.blob.models.BlobStorageException: Status code 403, "<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:294f4e24-301e-004f-7203-980252000000
Time:2020-10-01T14:56:40.4833994Z</Message><AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail></Error>"

I am using azure-store-blob v12.7.0

Thanks in advance.

Azure Storage Accounts
Azure Storage Accounts
Globally unique resources that provide access to data management services and serve as the parent namespace for the services.
2,810 questions
Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
2,535 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. deherman-MSFT 34,356 Reputation points Microsoft Employee
    2020-10-02T18:06:18.95+00:00

    @Pramit Bhaumik
    Apologies for the delay in responding here. BlobServiceClient.generateAccountSas is available, which should make this much simpler for you. Please try using this built in method for generating the account SAS and see if that works for you.

    Hope this helps! Let us know if you have any further questions or issues.

    -----------------

    Please don’t forget to "Accept the answer" and “up-vote” wherever the information provided helps you, this can be beneficial to other community members.