Azure / azure-storage-php

Microsoft Azure Storage Library for PHP
MIT License
217 stars 198 forks source link

How to create a SAS using a Stored Access Policy #324

Open georgeboot opened 2 years ago

georgeboot commented 2 years ago

Which service(blob, file, queue, table) does this issue concern?

blob

Which version of the SDK was used?

1.5.3

What's the PHP/OS version?

8.1.0

What problem was encountered?

I can't create a SAS using just a Stored Access Policy. The helpers always want a list of permissions and the expiry date.

However, when using Microsoft Azure Storage Explorer, I can generate a SAS that has only the sv, si, sr and sig.

When trying to create a SAS using BlobSharedAccessSignatureHelper::generateBlobServiceSharedAccessSignatureToken and by supplying the permissions and dates from the SAP, I do get a SAS url but it doesn't work.

Steps to reproduce the issue?

$accountName = 'testaccount';
$accountKey = 'blaaa';
$container = 'my-test-container';
$storedAccessPolicy = 'randomname';
// policy is set up to have `rawdl` permissions, and is valid between 2022-02-24T09:29Z and 2022-05-29T08:29Z

$helper = new BlobSharedAccessSignatureHelper($accountName, $accountKey);

$sas = $helper->generateBlobServiceSharedAccessSignatureToken(
    BlobResources::RESOURCE_TYPE_CONTAINER,
    $container,
    'rawdl',
    '2022-05-29T08:29Z',
    '2022-02-24T09:29Z',
    '',
    '',
    $storedAccessPolicy,
);

The helper outputs (SAS doesn't work):

sv=2017-11-09&sr=c&st=2022-02-24T09:29Z&se=2022-05-29T08:29Z&sp=rawdl&si=randomname&sig=hORQL7MeB0vDoqWQyS0CaNtH8bGELwo8iaX8i54WJPQ%3D

However, the Microsoft Azure Storage Explorer, generates the following through the UI (working SAS):

sv=2020-10-02&si=randomname&sr=c&sig=oI1XBqZHeGjRqEluyeMlb1tV%2Fy%2B0Vdm7wiJ0H43C5Lg%3D

I tried generating the SAS myself, but I can't figure out what to sign. The documentation is very vague about it.

I tried the following:

$stringToSign = implode("\n", [
    'rawdl',
    '2022-02-24T09:29Z',
    '2022-05-29T08:29Z',
    '/testaccount/my-test-container',
    'randomname',
    '2020-10-02',
]);

$stringToSign = implode("\n", [
    '/testaccount/my-test-container',
    'randomname',
    '2020-10-02',
]);

$stringToSign = implode("\n", [
    'rawdl',
    '2022-02-24T09:29Z',
    '2022-05-29T08:29Z',
    '/blob/testaccount/my-test-container',
    'randomname',
    '2020-10-02',
]);

$stringToSign = implode("\n", [
    '/blob/testaccount/my-test-container',
    'randomname',
    '2020-10-02',
]);

None of these work. They all produce incorrect signatures.

georgeboot commented 2 years ago

Turns out, the correct string to sign should be like this (reverse enigineered from Python SDK for Azure Blob):

$stringToSign = implode("\n", [
    '',
    '',
    '',
    "/blob/{$accountName}/{$container}",
    $storedAccessPolicy,
    '',
    '',
    '2020-10-02',
    'c',
    '',
    '',
    '',
    '',
    '',
    '',
]);