1
votes

Is it possible to open an SAS access to the entire blobs on one azure container ?

I can create a SAS to a specific blob, but I'm trying to do that for a container, and I don't find the good options ?

My goal is to open an specific access to the entire container and be able to read some specific blobs.

$end = date('Y-m-d\TH\:i\:s\Z', strtotime('+10 minutes'));

$containerName=$_POST['container'];
$blobName= $_POST['blob'];

function getSASForBlob($accountName, $container, $blob, $permissions ,$expiry, $key){
 /* Create the signature */
 $_arraysign = array();
 $_arraysign[] = $permissions;
 $_arraysign[] = '';
 $_arraysign[] = $expiry;
 $_arraysign[] = '/blob/'.$accountName . '/' . $container . '/';
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = "2015-12-11"; //the API version is now required 
 $_arraysign[] = '';
 $_arraysign[] = 'file; attachment';
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = 'binary';

 $_str2sign = implode("\n", $_arraysign);

 return base64_encode(hash_hmac('sha256', urldecode(utf8_encode($_str2sign)), base64_decode($key), true));
}

function getBlobUrl($accountName, $container, $blob, $resourceType, $permissions, $expiry, $_signature){
 /* Create the signed query part */
 $_parts = array();
 $_parts[] = (!empty($expiry))?'se=' .urlencode($expiry):'';
 $_parts[] = 'sr=' . $resourceType;
 $_parts[] = (!empty($permissions))?'sp=' . $permissions:'';
 $_parts[] = 'sig=' . urlencode($_signature);
 $_parts[] = 'sv=2015-12-11';
 $_parts[] = 'comp=list';


 /* Create the signed blob URL */
 $_url = 'https://'
 .$accountName.'.blob.core.windows.net/'
 . $container . '/'
 . $blob . '?'
 . implode('&', $_parts);

 return $_url;
 }


$sig = getSASForBlob("cloudviewer",$containerName, $blobName, "r", $end, $key);
$url = getBlobUrl("cloudviewer",$containerName,$blobName,"c","r", $end, $sig);

echo(json_encode(array('url' => $url, 'experity' => $end)));

My error is:

Signature did not match. String to sign used was r 2016-12-10T16:53:00Z /blob/cloudviewer/450-423-422-392 2015-12-11

2
Are you getting some HTTP error, can you share it please? Did you check that your expiration datetime is in UTC? According to documentation your code should work docs.microsoft.com/en-us/rest/api/storageservices/fileservices/…Ivan Ignatiev
I add the error result, the datetime is the good one, because I use the same to access directly to a specific blob.Lilice
It looks like you are creating a service SAS token. You may want to try creating an Account SAS token instead. I can tell it is a service SAS token because you have the sr parameter in there. docs.microsoft.com/en-us/rest/api/storageservices/fileservices/…Andrew W
Any update yet?Gary Liu

2 Answers

1
votes

In my test, we need to implement separate SAS tokens for blob and container operations. You can refer to https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/constructing-a-service-sas for details.

For this issue, is seems that you are generating SAS token URL for list blobs in container. For quick test, please try the following code snippet:

function getSASForBlob($accountName, $container, $blob, $permissions ,$expiry, $key){
 /* Create the signature */
 $_arraysign = array();
 $_arraysign[] = $permissions;
 $_arraysign[] = '';
 $_arraysign[] = $expiry;
 if($blob){
    $_arraysign[] = '/blob' .'/'.$accountName . '/' . $container . '/' . $blob;
 }else{
    $_arraysign[] = '/blob' .'/'.$accountName . '/' . $container ;
 }
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = "2015-12-11"; //the API version is now required 
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = '';

 $_str2sign = implode("\n", $_arraysign);

 return base64_encode(hash_hmac('sha256', urldecode(utf8_encode($_str2sign)), base64_decode($key), true));
}

function getBlobUrl($accountName, $container, $blob, $resourceType, $permissions, $expiry, $_signature){
 $_parts = array();
    $_parts[] = (!empty($expiry)) ? 'se=' . urlencode($expiry) : '';
    $_parts[] = 'sr=' . $resourceType;
    $_parts[] = (!empty($permissions)) ? 'sp=' . $permissions : '';
    $_parts[] = 'sig=' . urlencode($_signature);
    $_parts[] = 'sv=2015-12-11';
    $_parts[] = 'comp=list';
    $_parts[] = 'restype=container';


 /* Create the signed blob URL */
 $_url = 'https://'
 .$accountName.'.blob.core.windows.net/'
 . $container 
 // . '/'
 // . $blob 
 . '?'
 . implode('&', $_parts);

 return $_url;
 }

$sig = getSASForBlob(AZURE_ACC_NAME,AZURE_CONTAINER, null, "l", $endDate, AZURE_PRIMARY_KEY);
$url = getBlobUrl(AZURE_ACC_NAME,AZURE_CONTAINER,null,"c","l", $endDate, $sig);
0
votes

You need to make some minor modifications to generate a valid service SAS token that will list the blobs in a container. Also, when calling these methods you should pass in permissions of 'rl' not just 'r'. This is because you are wanting to list the items in a container.

$end = date('Y-m-d\TH\:i\:s\Z', strtotime('+10 minutes'));

$containerName=$_POST['container'];
$blobName= $_POST['blob'];

function getSASForBlob($accountName, $container, $blob, $permissions ,$expiry, $key){
 /* Create the signature */
 $_arraysign = array();
 $_arraysign[] = $permissions;
 $_arraysign[] = '';
 $_arraysign[] = $expiry;
 $_arraysign[] = '/blob/' . $accountName . '/' . $container;
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = "2015-12-11"; //the API version is now required 
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = '';

 $_str2sign = implode("\n", $_arraysign);

 return base64_encode(hash_hmac('sha256', urldecode(utf8_encode($_str2sign)), base64_decode($key), true));
}

function getBlobUrl($accountName, $container, $blob, $resourceType, $permissions, $expiry, $_signature){
 /* Create the signed query part */
 $_parts = array();
 $_parts[] = (!empty($expiry))?'se=' .urlencode($expiry):'';
 $_parts[] = 'sr=' . $resourceType;
 $_parts[] = (!empty($permissions))?'sp=' . $permissions:'';
 $_parts[] = 'sig=' . urlencode($_signature);
 $_parts[] = 'sv=2015-12-11';
 $_parts[] = 'comp=list';
 $_parts[] = 'restype=container';




 /* Create the signed blob URL */
 $_url = 'https://'
 .$accountName.'.blob.core.windows.net/'
 . $container . '?'
 . implode('&', $_parts);

 return $_url;
 }