Как получить подпись общего доступа к BLOB-объекту с помощью последней версии 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?


person Kzrystof    schedule 30.11.2019    source источник


Ответы (6)


Ответ Sajeetharan заставил меня искать 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);

Дополнение

Как упоминал @ one2012 в комментариях, несколько месяцев спустя, после этого ответа, была открыта страница, демонстрирующая все функции, обнаруженные в пространствах имен Azure.Storage. Ссылка может быть полезна для получения дополнительной информации.

person Kzrystof    schedule 01.12.2019
comment
Я не могу найти способ получить storageSharedKeyCredential из строки подключения вместо использования AccountName и AccountKey. Вы знаете какой-нибудь способ? - person Benjamin Talmard; 09.02.2020
comment
@benjamin var csBuilder = new DbConnectionStringBuilder(); csBuilder.ConnectionString = _configuration.GetConnectionString("MyCS"); var storageSharedKeyCredential = new StorageSharedKeyCredential( (string)csBuilder["AccountName"], (string)csBuilder["AccountKey"]); - person Nethemas; 01.04.2020
comment
если вы переходите в пространства имен Azure.Storage, эта страница - самое полезное, что я нашел craftedforeveryone.com/ - person ono2012; 12.08.2020
comment
вы, сэр, спасли мою жизнь и мое психическое здоровье - person Bogdan Banciu; 22.11.2020
comment
Мне потребовалось время, чтобы понять, что мой SDK устарел. Эта или более поздняя версия поддерживает все функции, указанные в этом ответе: ‹PackageReference Include = Azure.Storage.Blobs Version = 12.8.4 /› - person IdusOrtus; 27.05.2021

После изрядного количества поисков я нашел некоторую документацию 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
};
person Chris Alexander    schedule 29.01.2020

Использование клиентской библиотеки хранилища BLOB-объектов Azure версии 12 для .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/#generate_access_policy_based_sas_token_for_a_blob

person Kaarthikeyan    schedule 14.05.2020

Использование клиентской библиотеки хранилища 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();
person below43    schedule 05.12.2019

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/ говорит, что больше не используйте его.

person Phil Stollery    schedule 07.01.2020

Здесь: 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#:%7E:text=Authorization%20of%20a%20user%20delegation%20SAS,-When%20a%20client&text=This%20approach%20provides%20an%20additional,is%20a%20security%20best%20practice. для получения дополнительных сведений о том, почему это более безопасно (этот подход обеспечивает дополнительный уровень безопасности и позволяет избежать необходимости хранить ключ доступа к вашей учетной записи вместе с кодом приложения. По этим причинам создание SAS с помощью Azure AD учетные данные - лучшая практика безопасности.)

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

person Darren    schedule 12.11.2020