Как создать несколько сохраненных политик доступа для одного контейнера BLOB-объектов Azure?
Я прочитал и поиграл с примером кода в https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-shared-access-signature-part-2/
Затем я применил это к моему сценарию.
Я пишу инструмент для загрузки данных от партнера в хранилище BLOB-объектов Azure, после чего они будут использоваться некоторыми внутренними командами: YYYY-MM (контейнер) (DD-GUID) (префикс) File1.zip File2.zip ……
Я создал 2 политики для каждого контейнера: 1. Пишите только для партнеров, чтобы они могли писать только большие двоичные объекты и ничего больше. 2. Составьте список и прочитайте для наших внутренних команд, чтобы они могли перечислить и прочитать (загрузить) все большие двоичные объекты в контейнере.
Я думаю, что я могу просто передать правильную политику нужным получателям; Однако моя реализация не работает, как я ожидал.
Я создал 2 политики для каждого контейнера, используя метод ниже, конечно, с правильным разрешением для каждой политики:
static void CreateSharedAccessPolicy(CloudBlobClient blobClient, CloudBlobContainer container, string policyName)
{
//Create a new stored access policy and define its constraints.
SharedAccessBlobPolicy sharedPolicy = new SharedAccessBlobPolicy()
{
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(10),
Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List
};
//Get the container's existing permissions.
BlobContainerPermissions permissions = new BlobContainerPermissions();
//Add the new policy to the container's permissions.
permissions.SharedAccessPolicies.Clear();
permissions.SharedAccessPolicies.Add(policyName, sharedPolicy);
container.SetPermissions(permissions);
}
Сначала я создал политику только для записи, а затем политику чтения и списка. Что я заметил, так это то, что первая политика, похоже, не работает, все вернулось 403 Запрещено, а для второй политики единственное, что работает, это список BLOB-объектов, но не чтение (я пытался загрузить этот объект, но получил 404). Не обнаружена).
Кажется, я что-то упустил здесь. Не могли бы вы помочь мне понять, что не так с моим подходом?
В коде, который я использовал для проверки разрешений контейнера, я также заметил, что разрешение "Чтение" для контейнера на самом деле не работает, как указано где-то в документации Azure. Здесь я пытаюсь найти простой способ просто дать людям сохраненную политику доступа, чтобы они могли перечислять и загружать все большие двоичные объекты в контейнере, вместо того, чтобы предоставлять им подпись для каждого большого двоичного файла:
static void UseContainerSAS (string sas) {// Попробуйте выполнить контейнерные операции с предоставленным SAS.
//Return a reference to the container using the SAS URI.
CloudBlobContainer container = new CloudBlobContainer(new Uri(sas));
//Create a list to store blob URIs returned by a listing operation on the container.
List<Uri> blobUris = new List<Uri>();
try
{
//Write operation: write a new blob to the container.
CloudBlockBlob blob = container.GetBlockBlobReference("blobCreatedViaSAS.txt");
string blobContent = "This blob was created with a shared access signature granting write permissions to the container. ";
MemoryStream msWrite = new MemoryStream(Encoding.UTF8.GetBytes(blobContent));
msWrite.Position = 0;
using (msWrite)
{
blob.UploadFromStream(msWrite);
}
Console.WriteLine("Write operation succeeded for SAS " + sas);
Console.WriteLine();
}
catch (StorageException e)
{
Console.WriteLine("Write operation failed for SAS " + sas);
Console.WriteLine("Additional error information: " + e.Message);
Console.WriteLine();
}
try
{
//List operation: List the blobs in the container, including the one just added.
foreach (ICloudBlob blobListing in container.ListBlobs())
{
blobUris.Add(blobListing.Uri);
}
Console.WriteLine("List operation succeeded for SAS " + sas);
Console.WriteLine();
}
catch (StorageException e)
{
Console.WriteLine("List operation failed for SAS " + sas);
Console.WriteLine("Additional error information: " + e.Message);
Console.WriteLine();
}
try
{
CloudBlockBlob blob = container.GetBlockBlobReference(blobUris[0].ToString());
MemoryStream msRead = new MemoryStream();
msRead.Position = 0;
using (msRead)
{
blob.DownloadToStream(msRead);
Console.WriteLine(msRead.Length);
}
Console.WriteLine("Read operation succeeded for SAS " + sas);
Console.WriteLine();
}
catch (StorageException e)
{
Console.WriteLine("Read operation failed for SAS " + sas);
Console.WriteLine("Additional error information: " + e.Message);
Console.WriteLine();
}
Console.WriteLine();
try
{
//Delete operation: Delete a blob in the container.
CloudBlockBlob blob = container.GetBlockBlobReference(blobUris[0].ToString());
blob.Delete();
Console.WriteLine("Delete operation succeeded for SAS " + sas);
Console.WriteLine();
}
catch (StorageException e)
{
Console.WriteLine("Delete operation failed for SAS " + sas);
Console.WriteLine("Additional error information: " + e.Message);
Console.WriteLine();
}
}
1 ответ
На самом деле, ваша последняя операция стерла то, что вы сделали в первой операции. Чтобы избежать этого, вы должны прочитать существующие разрешения контейнера, добавить новое разрешение, а затем установить разрешения обратно в контейнер.
Вот правильный пример кода:
static void CreateSharedAccessPolicy(CloudBlobClient blobClient, CloudBlobContainer container, string policyName)
{
//Create a new stored access policy and define its constraints.
SharedAccessBlobPolicy sharedPolicy = new SharedAccessBlobPolicy()
{
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(10),
Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List
};
//Get the container's existing permissions.
BlobContainerPermissions permissions = container.GetPermissions();
//Add the new policy to the container's permissions.
permissions.SharedAccessPolicies.Add(policyName, sharedPolicy);
container.SetPermissions(permissions);
}
По причине, по которой вы столкнулись с ошибкой 404 при чтении больших двоичных объектов, расскажите, пожалуйста, код создания SAS по политике и как вы используете созданный SAS для чтения больших двоичных объектов, чтобы я мог помочь в устранении неполадок.
Ниже приведен пример кода для создания SAS и использования его для чтения больших двоичных объектов: (вы можете скопировать + вставить URL-адреса в stdout в браузер напрямую, чтобы попробовать)
var permissions = container.GetPermissions();
var policy = new SharedAccessBlobPolicy
{
Permissions = SharedAccessBlobPermissions.Read,
SharedAccessExpiryTime = DateTime.UtcNow.AddYears(1),
};
string policyName = "read";
permissions.SharedAccessPolicies.Add(policyName, policy);
container.SetPermissions(permissions);
string sas = container.GetSharedAccessSignature(null, policyName);
var blobs = container.ListBlobs(null, true);
Console.WriteLine("SAS = {0}", sas);
Console.WriteLine("Blobs URLs with SAS:");
foreach (var blob in blobs)
{
Console.WriteLine(blob.Uri.ToString() + sas);
}