Как получить подпись общего доступа для большого двоичного объекта с помощью последней версии Azure SDK .NET API v12?

Раньше у меня была возможность создать подпись общего доступа для большого двоичного объекта с помощью API пакета SDK для Azure v11, например:

var containerName = "mycontainer";
var blobName = "myblob";

CloudStorageAccount storageAccount 
 = CloudStorageAccount.Parse(<StorageConnectionString>);

CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

CloudBlobContainer container = blobClient.GetContainerReference(containerName);


SharedAccessBlobPermissions permission = SharedAccessBlobPermissions.Read;

TimeSpan clockSkew = TimeSpan.FromMinutes(15d);
TimeSpan accessDuration = TimeSpan.FromMinutes(15d);

var blobSAS = new SharedAccessBlobPolicy
{
    SharedAccessStartTime = DateTime.UtcNow.Subtract(clockSkew),
    SharedAccessExpiryTime = DateTime.UtcNow.Add(accessDuration) + clockSkew,
    Permissions = permissions
};

CloudBlockBlob blob = container.GetBlockBlobReference(blobName);

string sasBlobToken = blob.GetSharedAccessSignature(blobSAS);

...

Я хочу использовать последнюю версию v12 .NET API, которая, похоже, заменяет CloudBlobClient по BlobServiceClient, CloudBlobContainer по BlobContainerClient а также CloudBlockBlob по BlobClient.

Однако метод GetSharedAccessSignature который доступен на CloudBlockBlob экземпляр недоступен на BlobClient пример.

Вопрос

Как получить подпись общего доступа от BlobClient экземпляр с использованием последней версии Azure SDK .NET API v12?

7 ответов

Решение

Ответ Саджитарана заставил меня искать класс BlobSasBuilder, который действительно существует.

Вот как я могу построить его на сервере:

//  Creates a client to the BlobService using the connection string.
var blobServiceClient = new BlobServiceClient(storageConnectionString);

//  Gets a reference to the container.
var blobContainerClient = blobServiceClient.GetBlobContainerClient(<ContainerName>);

//  Gets a reference to the blob in the container
BlobClient blobClient = containerClient.GetBlobClient(<BlobName>);

//  Defines the resource being accessed and for how long the access is allowed.
var blobSasBuilder = new BlobSasBuilder
{
    StartsOn = DateTime.UtcNow.Subtract(clockSkew), 
    ExpiresOn = DateTime.UtcNow.Add(accessDuration) + clockSkew,
    BlobContainerName = <ContainerName>,
    BlobName = <BlobName>,
};

//  Defines the type of permission.
blobSasBuilder.SetPermissions(BlobSasPermissions.Write);

//  Builds an instance of StorageSharedKeyCredential      
var storageSharedKeyCredential = new StorageSharedKeyCredential(<AccountName>, <AccountKey>);

//  Builds the Sas URI.
BlobSasQueryParameters sasQueryParameters = blobSasBuilder.ToSasQueryParameters(storageSharedKeyCredential);

Вот как использовать его на стороне клиента:

//  Builds the URI to the blob storage.
UriBuilder fullUri = new UriBuilder()
{
    Scheme = "https",
    Host = string.Format("{0}.blob.core.windows.net", <AccountName>),
    Path = string.Format("{0}/{1}", <ContainerName>, <BlobName>),
    Query = sasQueryParameters.ToString()
};

//  Get an instance of BlobClient using the URI.
var blobClient = new BlobClient(fullUri.Uri, null);

//  Upload stuff in the blob.
await blobClient.UploadAsync(stream);

После изрядной охоты я нашел некоторую документацию Microsoft по этому поводу: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-user-delegation-sas-create-dotnet

В этих деталях используется ключ делегирования пользователя для создания SAS вместо ключа учетной записи, но изменение - это просто другая перегрузка для.ToSasQueryParameters(), как описано в других ответах.

Некоторые ключевые фрагменты из статьи, чтобы связать это. Сначала создайте свой BlobServiceClient:

// 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());

Получите ключ делегирования пользователя, он будет использован для генерации SAS:

// 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));

Наконец, создайте SAS URI:

// 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
};

Использование клиентской библиотеки хранилища BLOB-объектов Azure v12 для.NET:

BlobSasBuilder blobSasBuilder = new BlobSasBuilder()
{
    BlobContainerName = blobContainerName,
    BlobName = blobName,
    Resource = "b", //b = blob, c = container
    StartsOn = DateTimeOffset.UtcNow,
    ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(lifetimeMinutes)
};

blobSasBuilder.SetPermissions(BlobSasPermissions.Read);

StorageSharedKeyCredential storageSharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);

string sas = blobSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();

В случае, если общая подпись доступа (токен SAS) должна быть сгенерирована на основе политики доступа, назначенной контейнеру, используйте следующий метод

BlobSasBuilder blobSasBuilder = new BlobSasBuilder()
{
    BlobContainerName = blobContainerName,
    BlobName = blobName,
    Resource = "b", //b = blob, c = container
    Identifier = "ReadOnlyPolicy" //string value referees to the access policy created and assigned to the container.
};

StorageSharedKeyCredential storageSharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);

string sas = blobSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();

Примечание. Когда создание токена SAS основано на политике доступа, назначенной контейнеру, вы не сможете определить разрешения, время начала или окончания в BlobSasBuilder. Вы получите исключение во время выполнения, поскольку "Поля политики доступа могут быть связаны с подписью или идентификатором SAS, но не с обоими"

Ссылка: https://www.craftedforeveryone.com/beginners-guide-and-reference-to-azure-blob-storage-sdk-v12-dot-net-csharp/

https://www.craftedforeveryone.com/beginners-guide-and-reference-to-azure-blob-storage-sdk-v12-dot-net-csharp/

Здесь: https://docs.microsoft.com/en-us/rest/api/storageservices/delegate-access-with-shared-access-signature указано, что хранилище Azure поддерживает три разных типа подписи общего доступа (SAS).:

  1. SAS уровня учетной записи, который вы использовали в SDK v11. Подробности и пример здесь: https://docs.microsoft.com/en-us/azure/storage/common/storage-account-sas-create-dotnet
  2. Уровень обслуживания SAS с использованием SDK v12 (& V11). Подробности и пример здесь: https://docs.microsoft.com/en-us/azure/storage/blobs/sas-service-create?tabs=dotnet
  3. Делегирование пользователей SAS - рекомендуемый подход Microsoft, при условии, что вы можете использовать пользователя Azure Active Directory для подписки с использованием пакета SDK v12. Подробности и пример здесь: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-user-delegation-sas-create-dotnet

1 и 2 используют общий ключ учетной записи для генерации токена SAS, в то время как 3 использует ключ, сгенерированный пользователем учетной записи AAD, поэтому он более безопасен и более легко доступен для отзыва при необходимости (теоретически). См. Https://docs.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas#:~:text=Authorization%20of%20a%20user%20delegation%20SAS,-When%20a%20client&text= Этот%20approach% 20предоставляет% 20an% 20дополнительно, это% 20a% 20security% 20best% 20practice. для получения дополнительных сведений о том, почему это более безопасно ("Такой подход обеспечивает дополнительный уровень безопасности и позволяет избежать необходимости хранить ключ доступа к вашей учетной записи вместе с кодом приложения. По этим причинам создание SAS с использованием учетных данных Azure AD является наилучшей практикой безопасности..")

Теперь все они поддерживаются за счет хранения в использовании, но я получаю впечатление, что уровень счета либо не поддерживается для реализации в v12 SDK (я догадываясь - так что не цитируйте меня, но я не могу найти это либо) или есть какой-то другой скрытый способ сделать это (конечно, метод BlobSasBuilder.ToSasQueryParameters() имеет только две перегрузки), который, как я полагаю, оставляет подходы делегирования пользователя или уровня обслуживания в качестве того, что вы теперь должны реализовать.

В моем случае решение кажется довольно простым и элегантным:

Мой старый код:

          using Microsoft.Azure.Storage.Blob;
    private readonly CloudBlobContainer _container;
    private Uri GetSharedAccessUri(string filename)
    {
        var blob = _container.GetBlockBlobReference(filename);
        var sas = blob.GetSharedAccessSignature(new SharedAccessBlobPolicy
        {
            Permissions = SharedAccessBlobPermissions.Read,
            SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddYears(1)
        });
        return new Uri(blob.Uri, sas);
    }

Мой новый код:

          using Azure.Storage.Blobs;
    private readonly BlobContainerClient _container;
    private Uri GetSharedAccessUri(string filename)
    {
        var blob = _container.GetBlockBlobClient(filename);
        var sas = blob.GenerateSasUri((BlobSasPermissions)BlobContainerSasPermissions.Read, DateTime.UtcNow.AddYears(1));

        return new Uri(blob.Uri, sas);
    }
private string BuildSASUri(BlobClient blob)
{
    // Create a user SAS that only allows reading for a minute
    BlobSasBuilder sas = new BlobSasBuilder 
    {
        BlobContainerName = blob.BlobContainerName,
        BlobName = blob.Name,
        Resource = "b",
        ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(1)
    };
    // Allow read access
    sas.SetPermissions(BlobSasPermissions.Read);
    var storageSharedKeyCredential = new StorageSharedKeyCredential(
        _iconfiguration.GetValue<string>("StorageAccount:AccountName"),
        _iconfiguration.GetValue<string>("StorageAccount:AccountKey")
    );

    return sas.ToSasQueryParameters(storageSharedKeyCredential).ToString();
}

Это мой рабочий код.

Однако я не могу понять, как создать сохраненную политику доступа с V12. Должно быть так: https://docs.microsoft.com/en-us/dotnet/api/azure.storage.blobs.blobcontainerclient.setaccesspolicy?view=azure-dotnet

Но я думаю, что Microsoft полностью забыла предоставить способ создания BlobSignedIdentifier.

Документы устарели: https://docs.microsoft.com/en-us/azure/storage/common/storage-stored-access-policy-define-dotnet?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json

Которая использует Microsoft.Azure.Storage.Blob, но https://www.nuget.org/packages/Microsoft.Azure.Storage.Blob/ говорит, что больше не используйте его.

Использование клиентской библиотеки хранилища BLOB-объектов Azure v12 для.NET:

        BlobSasBuilder blobSasBuilder = new BlobSasBuilder()
        {
            BlobContainerName = blobContainerName,
            BlobName = blobName,
            Resource = "b", //b = blob, c = container
            StartsOn = DateTimeOffset.UtcNow,
            ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(lifetimeMinutes)
        };

        blobSasBuilder.SetPermissions(BlobSasPermissions.Read);

        StorageSharedKeyCredential storageSharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);

        string sas = blobSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();
Другие вопросы по тегам