Пользователь делегировал токен SAS - PullRequest
0 голосов
/ 23 февраля 2020

Я использую. NET core 3.0

Я пытаюсь создать приложение-демон, которое читает и записывает файлы в контейнер хранилища больших двоичных объектов. Я хотел бы использовать «маркер SAS, делегированный пользователем», так как это, кажется, лучшая практика.

Я попытался следовать инструкциям в Документах Microsoft , но столкнулся с проблемой. Я полагаю, что код должен записывать некоторые свойства ключа делегирования пользователя, но в моем случае он ничего не делает.

Я вошел в свою учетную запись в браузере (google Chrome ), которая имеет роль владельца подписки. Я подозреваю, что процесс аутентификации неправильный, и попробовал некоторые вещи (например, назначение ролей приложению, затем использование TokenCredential вместо DefaultAzureCredential ()), но ничего не изменилось.

Это фактический код. Я скопировал и вставил пример кода и просто добавил await blobClient.GetPropertiesAsync() для отладки. Результат кода просто "перед GetPropertiesAsyn c ()", и ошибок нет.

using System;
using System.IO;
using System.Threading.Tasks;
using Azure;
using Azure.Identity;
using Azure.Storage.Sas;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;

namespace TestUserDelegatedSAS
{
    class Program
    {
        static void Main(string[] args)
        {
            String accountName = "deleted";
            String containerName = "deleted";
            String blobName = "deleted.txt";
            GetUserDelegationSasBlob(accountName, containerName, blobName).GetAwaiter();

        }

        async static Task<Uri> GetUserDelegationSasBlob(string accountName, string containerName, string blobName)
        {
            // Construct the blob endpoint from the account name.
            string blobEndpoint = string.Format("https://{0}.blob.core.windows.net", accountName);

            // Create a new Blob service client with Azure AD credentials.  
            BlobServiceClient blobClient = new BlobServiceClient(new Uri(blobEndpoint),
                                                                    new DefaultAzureCredential());

            Console.WriteLine("before GetPropertiesAsync()");
            await blobClient.GetPropertiesAsync();
            Console.WriteLine("after GetPropertiesAsync()");

            // Get a user delegation key for the Blob service that's valid for seven days.
            // You can use the key to generate any number of shared access signatures over the lifetime of the key.
            UserDelegationKey key = await blobClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                                                DateTimeOffset.UtcNow.AddDays(7));

            // Read the key's properties.
            Console.WriteLine("User delegation key properties:");
            Console.WriteLine("Key signed start: {0}", key.SignedStartsOn);
            Console.WriteLine("Key signed expiry: {0}", key.SignedExpiresOn);
            Console.WriteLine("Key signed object ID: {0}", key.SignedObjectId);
            Console.WriteLine("Key signed tenant ID: {0}", key.SignedTenantId);
            Console.WriteLine("Key signed service: {0}", key.SignedService);
            Console.WriteLine("Key signed version: {0}", key.SignedVersion);
            Console.WriteLine();

            // Create a SAS token that's valid for one hour.
            BlobSasBuilder sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = containerName,
                BlobName = blobName,
                Resource = "b",
                StartsOn = DateTimeOffset.UtcNow,
                ExpiresOn = DateTimeOffset.UtcNow.AddHours(1)
            };

            // Specify read permissions for the SAS.
            sasBuilder.SetPermissions(BlobSasPermissions.Read);

            // Use the key to get the SAS token.
            string sasToken = sasBuilder.ToSasQueryParameters(key, accountName).ToString();

            // Construct the full URI, including the SAS token.
            UriBuilder fullUri = new UriBuilder()
            {
                Scheme = "https",
                Host = string.Format("{0}.blob.core.windows.net", accountName),
                Path = string.Format("{0}/{1}", containerName, blobName),
                Query = sasToken
            };

            Console.WriteLine("User delegation SAS URI: {0}", fullUri);
            Console.WriteLine();
            return fullUri.Uri;
        }

        private static async Task ReadBlobWithSasAsync(Uri sasUri)
        {
            // Try performing blob operations using the SAS provided.

            // Create a blob client object for blob operations.
            BlobClient blobClient = new BlobClient(sasUri, null);

            // Download and read the contents of the blob.
            try
            {
                // Download blob contents to a stream and read the stream.
                BlobDownloadInfo blobDownloadInfo = await blobClient.DownloadAsync();
                using (StreamReader reader = new StreamReader(blobDownloadInfo.Content, true))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        Console.WriteLine(line);
                    }
                }

                Console.WriteLine();
                Console.WriteLine("Read operation succeeded for SAS {0}", sasUri);
                Console.WriteLine();
            }
            catch (RequestFailedException e)
            {
                // Check for a 403 (Forbidden) error. If the SAS is invalid,
                // Azure Storage returns this error.
                if (e.Status == 403)
                {
                    Console.WriteLine("Read operation failed for SAS {0}", sasUri);
                    Console.WriteLine("Additional error information: " + e.Message);
                    Console.WriteLine();
                }
                else
                {
                    Console.WriteLine(e.Message);
                    Console.ReadLine();
                    throw;
                }
            }
        }

    }

}

Я действительно застрял здесь, и любой совет очень ценится. Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 24 февраля 2020

Согласно моим исследованиям, если вы хотите запросить ключ делегирования пользователя, для участника безопасности должно быть назначено действие Microsoft.Storage / storageAccounts / blobServices / generateUserDelegationKey . Мяу, следующие встроенные роли RBA C включают действие Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey. Подробнее см. В документе .

  • Автор

  • Участник учетной записи хранения

  • Автор данных хранилища BLOB-объектов

  • Владелец данных хранилища BLOB-объектов

  • Устройство чтения данных хранилища BLOB-объектов

  • Storage Blob Delegator

Кроме того, обратите внимание, что если вы используете Storage Blob Data Contributor, Storage Blob Data Owner, Storage Blob Data Reader и Storage Blob Delegator, мы не можем получить свойства учетной записи с этими роль. Поскольку эти роли не имеют разрешений для действий на уровне учетной записи. Другими словами, мы не можем вызвать метод BlobServiceClient.GetPropertiesAsync. Для получения более подробной информации, пожалуйста, обратитесь к официальному документу

Подробные шаги приведены ниже

  1. Создание субъекта службы
az ad sp create-for-rbac --name ServicePrincipalName \
    --role "Storage Blob Data Reader" \
--scope 

</subscriptions/<subscription>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>  
Код
var delegationKey = await blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddDays(7));
        BlobSasBuilder sasBuilder = new BlobSasBuilder()
        {
            BlobContainerName = containerName,
            BlobName = blobName,
            Resource = "b",
            StartsOn = DateTimeOffset.UtcNow,
            ExpiresOn = DateTimeOffset.UtcNow.AddHours(1)
        };
        sasBuilder.SetPermissions(BlobSasPermissions.Read);
        Console.WriteLine(sasBuilder.Permissions);
        var sasQueryParams = sasBuilder.ToSasQueryParameters(delegationKey, storageProviderSettings.AccountName).ToString();
        UriBuilder sasUri = new UriBuilder()
        {
            Scheme = "https",
            Host = string.Format("{0}.blob.core.windows.net", storageProviderSettings.AccountName),
            Path = string.Format("{0}/{1}", containerName, blobName),
            Query = sasQueryParams
        };

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...