Как получить подпись общего доступа для большого двоичного объекта с помощью последней версии 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://docs.microsoft.com/en-us/rest/api/storageservices/delegate-access-with-shared-access-signature указано, что хранилище Azure поддерживает три разных типа подписи общего доступа (SAS).:
- SAS уровня учетной записи, который вы использовали в SDK v11. Подробности и пример здесь: https://docs.microsoft.com/en-us/azure/storage/common/storage-account-sas-create-dotnet
- Уровень обслуживания SAS с использованием SDK v12 (& V11). Подробности и пример здесь: https://docs.microsoft.com/en-us/azure/storage/blobs/sas-service-create?tabs=dotnet
- Делегирование пользователей 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();