Thursday, November 27, 2025

Creating SAS URIs for Azure Storage Blobs using DefaultAzureCredential

When working with Azure Storage Blobs in .NET, you will often need to generate Shared Access Signature (SAS) URIs to provide temporary, secure access to your blob resources. 

However, if you're using DefaultAzureCredential for authentication we cannot simply call GenerateSasUri() on a BlobClient instance. 

BlobServiceClient blobServiceClient = new BlobServiceClient(
    new Uri($"https://{storageAccountName}.blob.core.windows.net"),
    new DefaultAzureCredential());

BlobClient blobClient = blobServiceClient
    .GetBlobContainerClient(containerName)
    .GetBlobClient(blobName);

// Throws exception: System.ArgumentNullException: Value cannot be null. (Parameter 'sharedKeyCredential')
Uri sasUri = blobClient.GenerateSasUri(BlobSasPermissions.Read, DateTimeOffset.UtcNow.AddMinutes(5));

That's because GenerateSasUri() requires SharedKeyCredential to sign the SAS token. When using DefaultAzureCredential, you don't have access to the storage account key.

The Quick (But Not Ideal) Workaround

For faster development and testing, many developers (myself included) have resorted to using connection strings with account keys:

BlobServiceClient blobServiceClient = new BlobServiceClient(
    $"DefaultEndpointsProtocol=https;AccountName={storageAccountName};AccountKey={accountKey};EndpointSuffix=core.windows.net");

BlobClient blobClient = blobServiceClient
    .GetBlobContainerClient(containerName)
    .GetBlobClient(blobName);

// Now GenerateSasUri() works
Uri sasUri = blobClient.GenerateSasUri(BlobSasPermissions.Read, DateTimeOffset.UtcNow.AddMinutes(5));

The Best Approach: User Delegation Keys

The recommended solution is to use User Delegation Keys. This approach allows you to generate SAS tokens using Azure AD credentials instead of storage account keys.

BlobServiceClient blobServiceClient = new BlobServiceClient(
    new Uri($"https://{storageAccountName}.blob.core.windows.net"),
    new DefaultAzureCredential());

BlobClient blobClient = blobServiceClient
    .GetBlobContainerClient(containerName)
    .GetBlobClient(blobName);

// Define the SAS validity period
var startsOn = DateTimeOffset.UtcNow.AddMinutes(-1);
var expiresOn = DateTimeOffset.UtcNow.AddMinutes(5);

// Build the SAS token configuration
var sasBuilder = new BlobSasBuilder
{
    BlobContainerName = containerName,
    BlobName = blobName,
    Resource = "b",
    StartsOn = startsOn,
    ExpiresOn = expiresOn,
};

sasBuilder.SetPermissions(BlobSasPermissions.Read);

// Get user delegation key from Azure AD (uses your Azure AD identity)
Response<UserDelegationKeyuserDelegationKey =
    await blobServiceClient.GetUserDelegationKeyAsync(startsOnexpiresOn);

// Generate SAS URI using user delegation key
var blobUriBuilder = new BlobUriBuilder(blobClient.Uri)
{
    Sas = sasBuilder.ToSasQueryParameters(
        userDelegationKey.Value,
        blobServiceClient.AccountName)
};

Uri sasUri = blobUriBuilder.ToUri();

And note this requires the identity to have Permission: Storage Blob Delegator.

Hope this helps.

Happy Coding.

Regards,
Jaliya

No comments:

Post a Comment