I’m currently facing an issue with uploading block blobs to Azure Blob Storage using the REST API. I’m constructing the string-to-sign as per the Azure documentation, but I’m consistently receiving a 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. error.
$str2sign = "PUTnnn$blockSizenn$blockMimeTypennnnnnx-ms-blob-type:BlockBlobnx-ms-date:$Datenx-ms-version:2019-12-12n$headerResourcen$urlResource";
Where $headerResource is x-ms-blob-type:BlockBlobnx-ms-date:$Datenx-ms-version:2019-12-12 and $urlResource is /$storageAccountname/$containerName/$blobNamenblockid:" . urlencode($blockId) . "ncomp:block".
I’m then creating the signature as follows:
<?php
$sig = base64_encode(hash_hmac('sha256', urldecode(utf8_encode($str2sign)), base64_decode($accesskey), true));
?>
And the authorization header:
<?php
$authHeader = "SharedKey $storageAccountname:$sig";
?>
The headers for the request are set as follows:
<?php
$headers = [
'Authorization: ' . $authHeader,
'x-ms-date: ' . $Date,
'x-ms-version: 2019-12-12',
'Content-Length: ' . strlen($blockList),
'Content-Type: application/xml',
];
?>
And the request is sent using curl:
<?php
curl_setopt($ch, CURLOPT_URL, $URL);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $blockList);
$result = curl_exec($ch);
?>
Despite following the documentation, I’m still facing this issue. I’ve also ensured that the Content-Length header is included in the string-to-sign if it is included in the request, and that the query parameters in the CanonicalizedResource part of the string-to-sign are in lexicographical order.
Interestingly, I have other functions for uploading and showing blobs that are working fine, which are using the same method for authentication. Here’s an excerpt from the show function:
<?php
// Azure Blob Storage download
$Date = gmdate('D, d M Y H:i:s GMT');
$headerResource = "x-ms-date:$Datenx-ms-version:2019-12-12";
$urlResource = "/$storageAccountname/$containerName/$blobName";
$arraysign = array();
$arraysign[] = 'GET'; /*HTTP Verb*/
$arraysign[] = ''; /*Content-Encoding*/
$arraysign[] = ''; /*Content-Language*/
$arraysign[] = ''; /*Content-Length (include value when zero)*/
$arraysign[] = ''; /*Content-MD5*/
$arraysign[] = ''; /*Content-Type*/
$arraysign[] = ''; /*Date*/
$arraysign[] = ''; /*If-Modified-Since */
$arraysign[] = ''; /*If-Match*/
$arraysign[] = ''; /*If-None-Match*/
?>
I would appreciate any guidance or suggestions on what might be causing this issue and how to resolve it.
Thank you.