1
votes

I am trying to make a GET request to get Account details of my Azure Blob Storage account, but it shows Auth failed each and every time. Can anyone tell whether the Header or Signature String formed is correct or is there any other issue?

Here's the code:

const account = process.env.ACCOUNT_NAME || "";
const key = process.env.ACCOUNT_KEY || "";

var strTime = new Date().toUTCString();
var strToSign =
  "GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:" +
  strTime +
  `\nx-ms-version:2018-03-28\n/${account}/\ncomp:properties\nrestype:account`;
var secret = CryptoJS.enc.Base64.parse(key);
var hash = CryptoJS.HmacSHA256(strToSign, secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var auth = `SharedKey ${account}:${hashInBase64}`;

const options = {
  url: `https://${account}.blob.core.windows.net/?comp=properties&restype=account`,

  headers: {
    Authorization: auth,
    "x-ms-date": strTime,
    "x-ms-version": "2018-03-28",
  },
};

function callback(error, response, body) {
  var json = parser.toJson(body);
  console.log(error);
  console.log(response);
  if (!error && response.statusCode == 200) {
    var json = parser.toJson(body);
    console.log(json);
  }
}

request(options, callback);

After this, the response.statusCode which I am getting is Status 403.

statusCode: 403,
statusMessage: 'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.',

The details about the azure-blob and headers and Auth could be found here: https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key

https://docs.microsoft.com/en-us/rest/api/storageservices/get-account-information

EDIT: The string param = has been corrected to :

1

1 Answers

1
votes

It will be much easier using Azure Storage JS SDK to make requests to Azure Blob Storage. If you want to get your storage account information, just try code below:

const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob");

const account = '<storage account name>'
const accountKey = '<storage account key>'

const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);

const blobServiceClient = new BlobServiceClient(
    `https://${account}.blob.core.windows.net`,
    sharedKeyCredential
);

blobServiceClient.getAccountInfo().then((result)=>{
    console.log("accountKind:"+result.accountKind + " skuName:" + result.skuName + " version:" + result.version );
})

Result:

enter image description here

Update:

If you want to try it in a more generic fashion, try the code below:

var CryptoJS = require("crypto-js");
var request = require("request");
var parser = require('body-parser')

const account = ''
const key = ''

var strTime = new Date().toUTCString();
var strToSign =
  "GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:" +
  strTime +
  `\nx-ms-version:2018-03-28\n/${account}/\ncomp:properties\nrestype:account`;

  //console.log(strToSign);
var secret = CryptoJS.enc.Base64.parse(key);
var hash = CryptoJS.HmacSHA256(strToSign, secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var auth = `SharedKey ${account}:${hashInBase64}`;

const options = {
  url: `https://${account}.blob.core.windows.net/?comp=properties&restype=account`,

  headers: {
    Authorization: auth,
    "x-ms-date": strTime,
    "x-ms-version": "2018-03-28",
  },
};

function callback(error, response, body) {
 
  console.log(body);
  if (!error && response.statusCode == 200) {
    
    console.log(response.headers["x-ms-sku-name"]);
  }
}

request(options, callback);

Result:

enter image description here

Seems you should use : instead of = in last param of your strToSign .