Issue Constructing SAS token in Laravel PHP leading to error: Signature did not match.

Collin Yarrington 0 Reputation points
2024-02-02T08:58:52.4966667+00:00

I am in the process of creating a SAS token in one of my Laravel PHP projects. The issue I am currently facing, is that when I construct the SAS token I get a "Signature did not match." error response from the storage REST API when attempting to upload a blob. Reason for using the REST API directly is because the PHP storage SDK has been deprecated to my knowledge .

Here is the code I am using to attempt the SAS token generation. Is there anything I am doing wrong? (Please do not recommend using the SDK)

public function generateSasToken($container)
    {
        $accountName = "<storage-account-name>";
        $signedPermissions = "rw";
        $signedStart = "2024-02-02T06:22:59Z";
        $signedExpiry = "2024-02-02T14:22:59Z";
        $signedIp = "";
        $protocol = "https";
        $signedVersion = "2022-11-02";
        $signedProtocol = "https";
        $accountKey = "<storage-account-access-key>";
        $canonicalizedResource = '/' . $accountName . '/' . $container;
        $signedIdentifier = '';
        $signedResource = "c";
        $signedSnapshotTime = "2018-11-09";
        $signedEncryptionScope = "";
        $rscc = "";
        $rscd = "";
        $rsce = "";
        $rscl = "";

        $stringToSign = $signedPermissions . "\n" .
            $signedStart . "\n" .
            $signedExpiry . "\n" .
            $canonicalizedResource . "\n" .
            $signedIdentifier . "\n" .
            $signedIp . "\n" .
            $signedProtocol . "\n" .
            $signedVersion . "\n" .
            $signedResource . "\n" .
            $signedSnapshotTime . "\n" .
            $signedEncryptionScope . "\n" .
            $rscc . "\n" .
            $rscd . "\n" .
            $rsce . "\n" .
            $rscl;

        // Signing the $stringToSign
        $signature = base64_encode(hash_hmac('sha256', $stringToSign, urlencode($accountKey), true));

        // Encoding signature
        $urlEncodedSignature = urlencode($signature);

        // Constructing the SAS token
        $sasToken = "?sv=" . $signedVersion .
            "&srt=" . $signedResource .
            "&sp=" . $signedPermissions .
            "&st=" . $signedStart .
            "&se=" . $signedExpiry .
            "&spr=" . $protocol .
            "&sig=" . $urlEncodedSignature;

        dd($sasToken);

Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
2,271 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Anand Prakash Yadav 3,140 Reputation points Microsoft Vendor
    2024-02-05T10:03:00.8266667+00:00

    Hello Collin Yarrington,

    Thank you for posting your query here!

    Can you please check with the code below and let us know if it helps to generate SAS token restricted to the specified container, providing container-level access with the specified permissions and time constraints.

    $accountName = config('azure.blob_storage.account_name');
    $accountKey = config('azure.blob_storage.access_key');
    $signedPermissions = "rw";
    $signedStart = now()->utc()->format('Y-m-d\TH:i:s\Z');
    $signedExpiry = now()->utc()->addHour()->format('Y-m-d\TH:i:s\Z');
    $protocol = "https";
    $signedVersion = "2017-04-17";
    $signedProtocol = "https";
    $signedResource = "c"; 
    
    $containerName = "your-container-name"; // Replace with your actual container name
    
    $stringToSign = $accountName . "\n";
    $stringToSign .= $signedPermissions . "\n";
    $stringToSign .= "b" . "\n";
    $stringToSign .= $signedResource . "\n";
    $stringToSign .= $containerName . "\n"; 
    $stringToSign .= "\n"; 
    $stringToSign .= $signedStart . "\n";
    $stringToSign .= $signedExpiry . "\n";
    $stringToSign .= "\n";
    $stringToSign .= $signedProtocol . "\n";
    $stringToSign .= $signedVersion . "\n";
    
    // Signing the $stringToSign
    $signature = base64_encode(hash_hmac('sha256', $stringToSign, base64_decode($accountKey), true));
    
    // Encoding signature
    $urlEncodedSignature = rawurlencode($signature);
    
    // Constructing the SAS token
    $sasToken = "?sv=" . $signedVersion .
        "&ss=b&srt=" . $signedResource .
        "&sp=" . $signedPermissions .
        "&st=" . $signedStart .
        "&se=" . $signedExpiry .
        "&spr=" . $protocol .
        "&sig=" . $urlEncodedSignature;
    
    dd($sasToken);
    

    Similar posts that might help:
    https://stackoverflow.com/questions/77751969/generating-sas-token-for-azure-blob-storage-in-php-with-rest-api

    https://stackoverflow.com/questions/77792702/subject-azure-blob-storage-issue-with-mac-signature-mismatch-in-block-blob-up

    https://stackoverflow.com/questions/77170696/php-curl-to-upload-video-to-azure-blob-storage/77171664#77171664

    Please let us know if you have any further queries. I’m happy to assist you further.  

    Please do not forget to "Accept the answer” and “up-vote” wherever the information provided helps you, this can be beneficial to other community members.