typescriptcypressazure-table-storageazurite

How to authenticate azurite REST API table storage?


I am trying to make a request to the Azurite api from a cypress test. I understand I need an authentication header and I tried using a nodejs script to generate the header. I keep getting an Unauthorized error when I try to query a table. I am not using the default ports for azurite but I'm not sure how that would affect this.

Request (I'm using Postman):

curl --location 'http://localhost:10012/devstoreaccount1/AuditLogs' \
--header 'Date: Mon, 10 Mar 2025 09:49:14 GMT' \
--header 'x-ms-version: 2025-01-05' \
--header 'Authorization: SharedKey devstoreaccount1:ttvHEM3DX/mmZ6LIMHEMEbNbS0SrR1UD+DLv6ej8+Tk=' \
--header 'Accept: application/json;odata=nometadata'

Node script for generating the auth code

const crypto = require('crypto');

const accountName = 'devstoreaccount1';
const accountKey = 'Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==';
const tableName = 'AuditLogs';
const date = new Date().toUTCString(); // Must be present in the request

// Canonicalized resource format for Table Storage
const canonicalizedResource = `/${accountName}/${tableName}`;

// Correct string-to-sign format for Table Storage
const stringToSign = `GET\n\n\n${date}\n${canonicalizedResource}`;

// Compute HMAC-SHA256 signature using the account key
const key = Buffer.from(accountKey, 'base64');
const hmac = crypto.createHmac('sha256', key);
hmac.update(stringToSign);
const signature = hmac.digest('base64');

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

console.log(`Date: ${date}`); // Ensure this is set in the request
console.log(`Authorization: ${authorizationHeader}`);

Solution

  • Here's my updated script that finally worked, thanks to your help! I had to put the account name twice in the resources, add parentheses to the table name and update the stringToSign a bit, I had the word GET which was unnecessary.

    const crypto = require('crypto');
    
    const accountName = 'devstoreaccount1';
    const accountKey = 'Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==';
    const tableName = 'AuditLogs()';
    const date = new Date().toUTCString();
    
    const canonicalizedResource = `/${accountName}/${accountName}/${tableName}`;
    
    const stringToSign = `${date}\n${canonicalizedResource}`;
    
    const signature = crypto
        .createHmac('sha256', Buffer.from(accountKey, 'base64'))
        .update(stringToSign, 'utf8')
        .digest('base64');
    
    const authorizationHeader = `SharedKeyLite ${accountName}:${signature}`;
    
    console.log(`Date: ${date}`);
    console.log(`Authorization: ${authorizationHeader}`);