Search code examples
c#azureasp.net-coreazure-storageazure-container-service

On Azure Storage, CanGenerateSasUri is always false


I have an ASP .Net Core 3.1 Web API which uses Azure Storage. For this, it was using the Microsoft.Azure.Storage.Blob library. The NuGet package manager informed me that this package was deprecated, and I should rather use Azure.Storage.Blobs. I did this, and proceeded to fix all the broken code as a result of this change. I didn't have many issues until I hit the code which generates a Shared Access Signature (SAS) for the client. Anyway, I managed to make it work, by following this code:

https://learn.microsoft.com/en-us/azure/storage/blobs/sas-service-create?tabs=dotnet

private static Uri GetServiceSasUriForContainer(BlobContainerClient containerClient,
                                          string storedPolicyName = null)
{
    // Check whether this BlobContainerClient object has been authorized with Shared Key.
    if (containerClient.CanGenerateSasUri)
    {
        // Create a SAS token that's valid for one hour.
        BlobSasBuilder sasBuilder = new BlobSasBuilder()
        {
            BlobContainerName = containerClient.Name,
            Resource = "c"
        };

        if (storedPolicyName == null)
        {
            sasBuilder.ExpiresOn = DateTimeOffset.UtcNow.AddHours(1);
            sasBuilder.SetPermissions(BlobContainerSasPermissions.Read);
        }
        else
        {
            sasBuilder.Identifier = storedPolicyName;
        }

        Uri sasUri = containerClient.GenerateSasUri(sasBuilder);
        Console.WriteLine("SAS URI for blob container is: {0}", sasUri);
        Console.WriteLine();

        return sasUri;
    }
    else
    {
        Console.WriteLine(@"BlobContainerClient must be authorized with Shared Key 
                          credentials to create a service SAS.");
        return null;
    }
}

However, the line Uri sasUri = containerClient.GenerateSasUri(sasBuilder); was giving me an error, and after further research I instead used:

StorageSharedKeyCredential credential = new StorageSharedKeyCredential(storageAccountName, storageAccountKey);

However, I also had to comment out the line if (containerClient.CanGenerateSasUri) because it is always false. Apparently it's because "BlobContainerClient must be authorized with Shared Key credentials to create a service SAS." But as far as I know, I am using Shared Key credentials. I am not using Azure AD Authentication (even though I am aware this is the recommended mnethod). My BlobServiceClient is being initialized like this:

string storageConnectionString = $"DefaultEndpointsProtocol=https;AccountName=propworx;AccountKey={storageAccountKey};EndpointSuffix=core.windows.net";
BlobServiceClient blobServiceClient = new BlobServiceClient(storageConnectionString);

Does anyone have any idea why CanGenerateSasUri is false?


Solution

  • "BlobContainerClient must be authorized with Shared Key credentials to create a service SAS." means that you should directly build the BlobContainerClient instead of BlobServiceClient with credentials, then pass it to GetServiceSasUriForContainer method.

    For example, use the code below:

            var storageAccountName = "xxx";
            var storageAccountKey = "xxx";
            var container_name = "xxx";
    
            StorageSharedKeyCredential credential = new StorageSharedKeyCredential(storageAccountName, storageAccountKey);
    
            //build the blob container url
            string blobcontainer_url = string.Format("https://{0}.blob.core.windows.net/{1}", storageAccountName, container_name);
    
            //directly build BlobContainerClient, then pass it to GetServiceSasUriForContainer() method
            BlobContainerClient blobContainer = new BlobContainerClient(new Uri(blobcontainer_url), credential);
    
            Uri mysasuri = GetServiceSasUriForContainer(blobContainer, null);
    

    The test result:

    enter image description here