Azure Table REST API - Make sure the value of Authorization header is formed correctly including the signature

57 Views Asked by At

I'm currently trying to set up my static web app to get/post data to my Azure Table using Vanilla Javascript. I'm trying to test the REST API using POSTMAN with a simple GET request. However, I'm an error:

The server failed to authenticate the request. Make sure the value of the Authorization header is formed correctly including the signature.

Here is my code:

    var date = new Date();
    var utcDate = date.toUTCString();
    CanonicalizedResource = "" + "/" + "accountname/" + 'Tables';
    ContentMD5 = "";
    ContentType = ""; //Should this be empty? I've tried application/json as well as text/plain
    StringToSign = "GET" + "\n" +
                    ContentMD5 + "\n" +
                    ContentType + "\n" + 
                    utcDate + "\n" +  
            CanonicalizedResource;  


    var hmac = computeHMACSHA256(StringToSign, 'key from Azure Table');
    console.log(StringToSign);
    console.log(utcDate);
    console.log(hmac);
function computeHMACSHA256(stringToSign, accountKey) {
    const key = Buffer.from(accountKey, "base64");
    return crypto.createHmac("sha256", key).update(stringToSign, "utf8").digest("base64");
} //this function is taken from the Javascript client service so that I could test.

In Postman, I have 4 headers in my GET request.

Authorization: SharedKey accountname:signature

Date: Date in GMT

x-ms-version: 2019-02-02

DataServiceVersion: 3.0;NetFx

I have read through the Azure documentation to create the signature, but still no luck. I've used the Azure Javascript client service to test the connection, and it works. For administrative purposes, I'd prefer to communicate with Tables using REST HTTP requests.

Unfortunately, I was unable to find anything through searching with this specific setup. I've verified it works using SharedKeyLite (through the client service). I'm thinking something is wrong with my StringToSign, but still unsure.

Hoping someone can see what's wrong here.

1

There are 1 best solutions below

1
Hugo Barona On BEST ANSWER

It looks like you're attempting to manually generate the Shared Key Lite authentication for an Azure Table Storage request. The issue could be related to the way you're constructing the StringToSign and the Authorization header.

Here's an alternative version of your code with some explanations:

const crypto = require('crypto');

// Function to compute HMAC-SHA256
function computeHMACSHA256(stringToSign, accountKey) {
    const key = Buffer.from(accountKey, "base64");
    return crypto.createHmac("sha256", key).update(stringToSign, "utf8").digest("base64");
}

// Construct the request headers
const date = new Date().toUTCString();
const canonicalizedResource = "/" + "accountname/" + 'Tables';
const contentMD5 = "";
const contentType = "";  // Use application/json if you're sending JSON data
const stringToSign = `GET\n${contentMD5}\n${contentType}\n${date}\n${canonicalizedResource}`;

// Replace 'key from Azure Table' with your actual account key
const signature = computeHMACSHA256(stringToSign, 'key from Azure Table');

// Construct the Authorization header
const authorizationHeader = `SharedKey accountname:${signature}`;

console.log("StringToSign:", stringToSign);
console.log("Date:", date);
console.log("Authorization Header:", authorizationHeader);

Note: Make sure to replace 'key from Azure Table' with your actual Azure Table Storage account key.

Additionally, when constructing the StringToSign, ensure that the CanonicalizedResource includes the specific table name you're interacting with.

For example, if your table is named 'MyTable', the CanonicalizedResource should be "/accountname/Tables/MyTable".