Я столкнулся с проблемой при создании URL-адреса подписи общего доступа (SAS) для файла в хранилище BLOB-объектов Azure с использованием управляемого удостоверения. Сгенерированный URL-адрес SAS содержит знак «+» в поле подписи, что приводит к ошибке «Поля подписи сформированы неправильно» при попытке использовать URL-адрес для доступа.
public string GenerateSaS(string account,
string containerName,
string fileName,
int expiryTimeInMins)
{
try
{
var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = Environment.GetEnvironmentVariable("<My CLient Id>") });
BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri($"https://{account}.blob.core.windows.net/"), tokenCredential);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
// Check if the container exists
if (!containerClient.Exists())
{
return null;
}
// Create a BlobSasBuilder instance
var sharedPolicy = new BlobSasBuilder
{
StartsOn = DateTimeOffset.UtcNow,
ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(expiryTimeInMins),
ContentDisposition = $"attachment;filename = {fileName}",
BlobContainerName = containerName,
BlobName = fileName,
Resource = "b", // Blob-level access
Protocol = SasProtocol.Https // Use HTTPS only
};
sharedPolicy.SetPermissions(BlobSasPermissions.Read | BlobSasPermissions.Write | BlobSasPermissions.Create);
// Generate SAS token and create BlobUriBuilder
BlobClient blobClient = containerClient.GetBlobClient(fileName);
var blobUriBuilder = new BlobUriBuilder(blobClient.Uri)
{
Sas = sharedPolicy.ToSasQueryParameters(blobServiceClient.GetUserDelegationKey(DateTimeOffset.UtcNow.AddMinutes(-2), DateTimeOffset.UtcNow.AddMinutes(2)), blobServiceClient.AccountName)
};
// Convert BlobUriBuilder to URL string
var url = blobUriBuilder.ToUri().ToString();
return url;
}
catch (Exception ex)
{
// Handle exception
throw ex;
}
}
Образец подписи в URL => sig=7SAJlSwRz8RNMQkEV4Y+hfIMEfVIRFapY49U/vqf4cI=
Я пробовал разные способы создания URL-адреса, но безуспешно. Я ожидаю рабочего решения этой проблемы
Проблема с созданием URL-адреса SAS хранилища BLOB-объектов Azure с управляемым удостоверением
Вы можете использовать приведенный ниже код для создания URL-адреса SAS хранилища BLOB-объектов Azure с помощью кода .Net.
Код:
using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Sas;
namespace SAStoken
{
class Program
{
private static void Main()
{
var account = "venkat123";
var containerName = "test";
var fileName = "imp.png";
var Credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = Environment.GetEnvironmentVariable("<My CLient Id>") });
BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri($"https://{account}.blob.core.windows.net/"), Credential);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
BlobClient blobClient = containerClient.GetBlobClient(fileName);
var userDelegationKey = blobServiceClient.GetUserDelegationKey(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddDays(1));
var sasBuilder = new BlobSasBuilder()
{
BlobContainerName = blobClient.BlobContainerName,
BlobName = blobClient.Name,
Resource = "b", // b for blob, c for container
StartsOn = DateTimeOffset.UtcNow,
ExpiresOn = DateTimeOffset.UtcNow.AddHours(4),
Protocol = SasProtocol.Https
};
sasBuilder.SetPermissions(BlobSasPermissions.Read | BlobSasPermissions.Write | BlobSasPermissions.Create);
BlobUriBuilder blobUriBuilder = new BlobUriBuilder(blobClient.Uri)
{
// Specify the user delegation key.
Sas = sasBuilder.ToSasQueryParameters(userDelegationKey, blobServiceClient.AccountName)
};
Console.WriteLine("BlobSAS URI: {0}", blobUriBuilder);
}
}
}
Выход:
BlobSAS URI: https://venkat123.blob.core.windows.net/test/imp.png?skoid=6xxxxxx&sktid=72fxxxxxx-41af-91ab-2d7xxb47&skt=2024-04-29T07%3A16%3A33Z&ske=2024-04-30T07%3A16%3A33Z&sks=b&skv=2023-11-03&sv=2023-11-03&spr=https&st=2024-04-29T07%3A16%3A37Z&se=2024-04-29T11%3A16%3A37Z&sr=b&sp=rcw&sig=reHWCZ0lNDyBGxxxxxfH4Z3I7E%3D
Браузер:
Сработал ли описанный выше подход для вас?
Удален ContentDisposition
, чтобы игнорировать загрузку вместо просмотра изображения.
Да, это сработало для меня. Но я не понимаю, почему сработало удаление ContentDisposition? И что в этом случае отличается от того, что я не получил знак плюса?
Я использовал ContentDisposition
в своем коде, например i.imgur.com/Y5PFDo2.png Когда я скопировал и вставил URL-адрес в браузер, он будет загружен i.imgur.com/r6df6W3.png
Есть идеи, почему это сработало?
В предоставленном мною прокомментированном коде свойство ContentDisposition
включено, но оно закодировано в URL-адресе с использованием метода Uri.EscapeDataString. Этот метод заменяет знак «+» на «%2B», который является допустимым символом в URL-адресе. Таким образом, токен SAS генерируется без каких-либо проблем.
Я не понял, вы удалили ContentDisposition. На каком этапе убрали знак +?
Можете ли вы рассказать немного о том, в чем разница, которую вы сделали? Я вижу удаление контента и получение ключа делегирования раньше?