I've combed through at least a dozen different versions of this problem but none of them have so far produced an answer to the one I'm having. I'm attempting to develop a proof-of-concept for retrieving an image from Azure BLOB storage using Azurite and a service SAS with a corresponding storage account key. I'm using the well-known storage account credentials for Azurite as indicated here. There appear to be innumerable ways to do this kind of thing in C# but I opted to loosely follow this example and ended up with something like this:
public Uri GetSharedKeySasUrl()
{
BlobServiceClient serviceClient = new BlobServiceClient(
new Uri("http://127.0.0.1:10000/devstoreaccount1/"),
new Azure.Storage.StorageSharedKeyCredential(
"devstoreaccount1",
"Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
)
);
var blobContainer = serviceClient.GetBlobContainerClient("images");
var blobClient = blobContainer.GetBlobClient("00000-pano.jpg");
BlobSasBuilder sasBuilder = new BlobSasBuilder()
{
BlobContainerName = "images",
BlobName = "00000-pano.jpg",
Resource = "b",
StartsOn = DateTimeOffset.UtcNow,
ExpiresOn = DateTimeOffset.UtcNow.AddHours(1)
};
sasBuilder.SetPermissions(BlobSasPermissions.Read);
Uri sasUri = blobClient.GenerateSasUri(sasBuilder);
Debug.WriteLine("SAS URI for blob is: {0}", sasUri);
return sasUri;
}
This produces a URL that looks as though it should work just fine, but whenever I paste it into a browser and attempt to access it I consistently get the following:
<Error>
<Code>AuthorizationFailure</Code>
<Message>Server failed to authenticate the request. Make sure the value of the Authorization header is formed correctly including the signature. RequestId:551902dd-ecb8-4736-9cf1-32406d98c02f Time:2022-04-11T20:18:06.368Z</Message>
</Error>
Conversely, if I generate a SAS signature through the Microsoft Azure Storage Explorer, that URL works perfectly. If I compare this URL to the URL this method generates, both seem to be perfectly well-formatted - I can't see anything that would suggest mine is malformed.
Generated by the method:
http://127.0.0.1:10000/devstoreaccount1/images/00000-pano.jpg?sv=2021-04-10&st=2022-04-11T20%3A17%3A59Z&se=2022-04-11T21%3A17%3A59Z&sr=b&sp=r&sig=bUHI2562NmvvtflOqT5kr0E%2BnZv7Q12PlR%2FGNPmEhL8%3D
Generated in Storage Explorer:
http://127.0.0.1:10000/devstoreaccount1/images/00000-pano.jpg?sv=2018-03-28&st=2022-04-11T20%3A06%3A47Z&se=2022-04-12T20%3A06%3A47Z&sr=b&sp=r&sig=V6N7uWDGgoVx8wirM%2FP1ou2kbg05PB4D%2BG8YQdvS5RU%3D
The only notable difference seems to be the version of the service each one is using - the explorer uses 2018-03-28
while the method uses 2021-04-10
. I've tried assigning the version in the BlobSasBuilder but it just gets ignored, which is consistent with Microsoft's own remarks about the property being deprecated and the class always using the latest supported version of the service regardless of what you specify here. I still don't think that explains the issue, though.
Any ideas? Thanks in advance for the help.
EDIT
I remain hopelessly stuck on this. I've made numerous attempts to reformulate the code I'm using to construct the SAS URI in hopes that something might work. Not a single one has worked so far. The methods I've tried:
BlobUriBuilder
, SasBuilder
and StorageSharedKeyCredential
to generate the URIBlobServiceClient
with a StorageSharedKeyCredential
to derive the BlobContainerClient
and in turn the BlobClient
, and then the SasBuilder
to generate the URIBlobServiceClient
in place of a StorageSharedKeyCredential
"UseDevelopmentStorage=true"
as the connection string with the BlobServiceClient
HMACSHA256
and a NameValueCollection
to construct the query parametersI've also experimented with running Azurite using different startup options, including azurite --loose
and azurite --skipApiVersionCheck
. Neither one makes any difference.
Other things I've tried:
I simply can't understand why this would be such an insurmountable problem. Please help.
Updated Solution:
I have tested Azure.Storage.Blobs package version 12.11.0, and gives the exact issue OP described in the question.
Changing this to version 12.10.0 solved the problem.
This makes a conclusion that version 12.11.0 must either be a side effect of a breaking change or a bug.
So until Microsoft comes up with a solution or answer, the solution is to use version 12.10.0.
Original answer:
I have tested your code and it works, I do not get the error you have. I guess you either need to reinstall the latest version of Azurite or do it the way I did it and it worked for me.
To ensure the consistency of my work, I used docker to install azurite.
I use Windows 11 and Docker Desktop, more about installation check Microsoft doc.
docker pull mcr.microsoft.com/azure-storage/azurite
Then
docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 -v c:/azurite:/data mcr.microsoft.com/azure-storage/azurite
Now we have docker up and running, I use Microsoft Azure Storage Explorer to create a blob container and upload the image 00000-pano.jpg (it is a flower image).
Now I take your code without changing anything in it and run it in my console application with package reference
<PackageReference Include="Azure.Storage.Blobs" Version="12.10.0" />
And running the code, I get the following URL:
http://127.0.0.1:10000/devstoreaccount1/images/00000-pano.jpg?sv=2020-08-04&st=2022-04-20T10%3A47%3A00Z&se=2022-04-20T11%3A47%3A00Z&sr=b&sp=r&sig=RHHe5NJRjhbOjoTeCONqhrRHjjJCygOa8urcwzOWpeE%3D
I copy and paste the URL into my browser and I get the flower without authentication issues:
The following is my console for docker and logs of what I was doing with the image:
Disclaimer: I have some articles about Azurite and docker, testing Azure code with Azurite, and mocking Azure storage this might add value to your further work. (https://itbackyard.com/tag/azurite/)