We are trying to insert a json object to an Azure table, but we keep getting the following exception when making the rest call:
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
The created Authorization header matches the format given in https://learn.microsoft.com/en-us/azure/storage/common/storage-rest-api-auth?toc=%2Fazure%2Fstorage%2Ftables%2Ftoc.json
"SharedKey <storage account name>:<signature>"
With some slight modifications, we can get this basic script create a blob in blob storage, but we need to save the json object to table storage. The following solution works for blob storage but we have not gotten it to work with table storage: Simple PHP cURL file upload to Azure storage blob
We believe the following snippet should work, however, we still get the above mentioned authorization exception.
function sendTableEntries($jsonData, $storageAccount, $tablename, $destinationURL, $accesskey) {
echo $jsonData, $storageAccount, $tablename, $destinationURL, $accesskey;
$currentDate = gmdate("D, d M Y H:i:s T", time());
$contLen = strlen($jsonData);
$headerResource = "x-ms-blob-cache-control:max-age=3600\nx-ms-blob-type:BlockBlob\nx-ms-date:$currentDate\nx-ms-version:2017-07-29";
$urlResource = "/$storageAccount/$tablename";
$arraysign = array();
$arraysign[] = 'POST'; /*HTTP Verb*/
$arraysign[] = ''; /*Content-Encoding*/
$arraysign[] = ''; /*Content-Language*/
$arraysign[] = $contLen; /*Content-Length (include value when zero)*/
$arraysign[] = ''; /*Content-MD5*/
$arraysign[] = 'application/json'; /*Content-Type*/
$arraysign[] = ''; /*Date*/
$arraysign[] = ''; /*If-Modified-Since */
$arraysign[] = ''; /*If-Match*/
$arraysign[] = ''; /*If-None-Match*/
$arraysign[] = ''; /*If-Unmodified-Since*/
$arraysign[] = ''; /*Range*/
$arraysign[] = $headerResource; /*CanonicalizedHeaders*/
$arraysign[] = $urlResource; /*CanonicalizedResource*/
$str2sign = implode("\n", $arraysign);
$sig = base64_encode(hash_hmac('sha256', urldecode(utf8_encode($str2sign)), base64_decode($accesskey), true));
$authHeader = "SharedKey $storageAccount:$sig";
//echo "sig is " . $sig;
//echo " Auth header is " . $authHeader;
$headers = array( 'Authorization: ' . $authHeader,
'x-ms-blob-cache-control: max-age=3600',
'x-ms-blob-type: BlockBlob',
'x-ms-date: ' . $currentDate,
'x-ms-version: 2017-07-29',
'Content-Type: application/json',
'Content-Length: ' . $contLen );
$ch = curl_init($destinationURL);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSLVERSION, 6);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
$result = curl_exec($ch);
echo ('Result<br/>');
print_r($result);
echo ('Error<br/>');
print_r(curl_error($ch));
curl_close($ch);
}
$accesskey = "ACCESSKEY";
$storageAccount = 'storageaccount';
$tablename = 'tablename';
$temp = array();
$temp["PartitionKey"] = "5432";
$temp["RowKey"] = "234235";
$temp["value"] = 3455;
$temp["valid"] = 1;
$content = json_encode($temp);
$destinationTable = "https://$storageAccount.table.core.windows.net/$tablename";
sendTableEntries($content, $storageAccount, $tablename, $destinationTable, $accesskey);
Does anyone know what is wrong with the above code so that we can successfully insert json to azure tables? Note that the php version is too old to support the Azure SDK for PHP.