1

I am trying to upload the blob in a azure storage container using REST APIs(note:container is already created). But i am getting error as "status: 403, statusText: 'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.'"

I have prepared the request and signed with decoded access keys, and converting the same in base64 format. but still getting error. I am sharing the typescript code, please help me to find where I am doing mistake.

import fetch from 'node-fetch';
import defaults  from  "../modules/defaults";
import { createHmac } from "crypto";

    async function uploadBlob(){
        
        let data = "sampletest";
        let dataLength = (data.length).toString()
        console.log("dataLength\n",dataLength)
        
       
        let accountKey = `account key looks like MSUUUMyhMSU..`;
        console.log("key\n",accountKey);
        let blob_type = "BlockBlob";
        let request_time = new Date().toUTCString();
        let api_version = "2015-02-21"
        try{
           
            let string_params = {
                'verb': 'PUT',
                'Content-Encoding': '',
                'Content-Language': '',
                'Content-Length': dataLength,
                'Content-MD5': '',
                'Content-Type': '',
                'Date': '',
                'If-Modified-Since': '',
                'If-Match': '',
                'If-None-Match': '',
                'If-Unmodified-Since': '',
                'Range': '',
                'CanonicalizedHeaders': 'x-ms-blob-type:' + blob_type + '\nx-ms-date:' + request_time + '\nx-ms-version:' + api_version,
                'CanonicalizedResource': '/' + "pcatest" +'/'+ "pca-al" + '/' + "newBlob"
            }
            
            let string_to_sign = (string_params['verb'] + '\n' 
                              + string_params['Content-Encoding'] + '\n'
                              + string_params['Content-Language'] + '\n'
                              + string_params['Content-Length'] + '\n'
                              + string_params['Content-MD5'] + '\n' 
                              + string_params['Content-Type'] + '\n' 
                              + string_params['Date'] + '\n' 
                              + string_params['If-Modified-Since'] + '\n'
                              + string_params['If-Match'] + '\n'
                              + string_params['If-None-Match'] + '\n'
                              + string_params['If-Unmodified-Since'] + '\n'
                              + string_params['Range'] + '\n'
                              + string_params['CanonicalizedHeaders']
                              + string_params['CanonicalizedResource'])
          
            console.log("reqHeaders \n",string_to_sign);
            let reqHeaderHash = computeHMACSHA256(string_to_sign,accountKey);
            
            console.log("==============rearheaderHash=============\n",reqHeaderHash);

            let signature = `SharedKey ${defaults.accountName}:${reqHeaderHash}`;
            console.log("==============signature=============\n",signature);
            const url = "https://test.blob.core.windows.net/testcontainer/newblob";
            console.log("url",url);
            const response = await fetch(url,{
                method:"PUT",
                body: data,
                headers : {
                    "x-ms-date" : request_time,
                    "x-ms-version" : api_version,
                    "Content-Length": dataLength,
                    "x-ms-blob-type": blob_type,
                    "Authorization" : signature
                }  
            });
            console.log("============response==============\n",response);
            }
            catch(err)
            {
                console.log("error",err);
            }
        
    }
    

function computeHMACSHA256(stringToSign: string, accountKey: string): string {
  const key = Buffer.from(accountKey, "base64")
    console.log("key\n",key);
    return createHmac("sha256", key)
        .update(stringToSign, "utf8")
        .digest("base64");
}
    uploadBlob();
kira
  • 9
  • 3

1 Answers1

0

please check for below points.

  1. If your shared account key is correct(It is case sensitive)(also see if sas expired ) , try to use new key by refreshing and try again.
  2. Check if clock on your computer is correct. you need to see is if your computer's clock is slower than the GMT time. .(see this thread to set the time).
  3. Check x-ms-version , as it may point to older version by default and add the later version and see.Do check the szure storage version if it has to be updated.
  4. Try to generate sas key using Key 2 in azure portal and also update the connection string according to that.

Note: Try to use SAS key instead of account key as anyone with these credentials can do anything they want to your data in that account as account key is exposed

similar issue

References:

  1. About apps and programming (programtheeworld.com)

  2. Authorize with Shared Key (REST API) - Azure Storage | Microsoft Docs

kavyaS
  • 8,026
  • 1
  • 7
  • 19
  • Thank you kavya. I found that the issue was with the formatting syntax. so i tried the same using azure SDK functions. Then it was working. – kira Sep 24 '21 at 08:57