I am making a call to an internal API that returns data that I analyze, process and create a spreadsheet which i then save in a storage account, I then create a record in a reporting tool that includes the link to download the blob that was created using StorageSharedKeyCredential
and an Account key
. This works well until the key rotates in Azure. How can I get access to the blob without managing the access key?
Currently I have a function that Generates an SAS token for the blob like
private string GenerateSasToken(BlobClient blobClient)
{
// Define the SAS token parameters
BlobSasBuilder sasBuilder = new BlobSasBuilder
{
BlobContainerName = blobClient.BlobContainerName,
BlobName = blobClient.Name,
Resource = "b" // "b" for blob, "c" for container
};
// Set the permissions and the expiry time for the SAS token
sasBuilder.SetPermissions(BlobSasPermissions.Read | BlobSasPermissions.Write);
sasBuilder.ExpiresOn = DateTimeOffset.UtcNow.AddMonths(6).AddHours(1);
// Generate the SAS token using the storage account key
BlobUriBuilder blobUriBuilder = new BlobUriBuilder(blobClient.Uri);
StorageSharedKeyCredential storageCredentials = new StorageSharedKeyCredential(blobUriBuilder.AccountName, this.accountKey);
return sasBuilder.ToSasQueryParameters(storageCredentials).ToString();
}
How can get access to the blob without managing the access key?
According to this MS-Document
You can be able to access the blob without using access key but the user needs RBAC
role to access the storage account.
You need Storage Blob delegator
or Storage Blob Data contributor
role to generate the SAS token and access the blob in the Azure storage account.
Code:
using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Sas;
using System;
class Program
{
public static void Main(string[] args)
{
var containerName = "test";
var storageAccountName = "venkat326123";
var blobName = "scenery.jpg";
var url = $"https://{storageAccountName}.blob.core.windows.net";
// Initialize BlobServiceClient using DefaultAzureCredential
var blobServiceClient = new BlobServiceClient(new Uri(url), new DefaultAzureCredential());
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
// Get User Delegation Key
var userDelegationKey = blobServiceClient.GetUserDelegationKey(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddDays(1));
var sasBuilder = new BlobSasBuilder()
{
BlobContainerName = containerName,
BlobName = blobName,
Resource = "b",
StartsOn = DateTimeOffset.UtcNow,
ExpiresOn = DateTimeOffset.UtcNow.AddDays(1),
};
sasBuilder.SetPermissions(BlobSasPermissions.Read | BlobSasPermissions.Write);
// Construct the Blob URI with SAS token
var blobUriBuilder = new BlobUriBuilder(containerClient.Uri)
{
BlobName = blobName,
Sas = sasBuilder.ToSasQueryParameters(userDelegationKey, blobServiceClient.AccountName)
};
var blobUriWithSas = blobUriBuilder.ToUri();
Console.WriteLine(blobUriWithSas);
}
}
Output:
https://venkat326123.blob.core.windows.net/test/scenery.jpg?skoid=63682e3exxx5d59218&sktid=9329xxxxaf6d&skt=2024-10-16T09%3A40%3A19Z&ske=2024-10-17T09%3A40%3A19Z&sks=b&skv=2024-05-04&sv=2024-05-04&st=2024-10-16T09%3A40%3A26Z&se=2024-10-17T09%3A40%3A26Z&sr=b&sp=rw&sig=redacted
To test, I'm using the above SAS
URL to access for validation.
Browser:
Also, Refer the Tiny Wang's comment which is very helpful to authenticate with storage account.
Reference: Create a user delegation SAS - Azure Storage | Microsoft Learn