Azure / Azurite

A lightweight server clone of Azure Storage that simulates most of the commands supported by it with minimal dependencies
MIT License
1.74k stars 309 forks source link

SAS download returns 403 #2412

Open danjohnso opened 2 weeks ago

danjohnso commented 2 weeks ago

Which service(blob, file, queue, table) does this issue concern?

Blob

Which version of the Azurite was used?

Tested in 3.28.0 from Visual Studio initially, tried upgrading to 3.30.0 with VS Code as well

Where do you get Azurite? (npm, DockerHub, NuGet, Visual Studio Code Extension)

VS Code and Visual Studio 2022

What's the Node.js version?

20.10.0

What problem was encountered?

When trying to download file with a SAS token url, I get a 403 back from Azurite. Connecting to real storage account returns file as expected.

Steps to reproduce the issue?

Tried azurite versions from Visual Studio and VS Code (version info above). Using oauth, https and fixed file location. Flags like so:

--location D:\azurite --oauth basic --cert D:\code\app\.cert\127-cert.pem --key D:\code\app\.cert\127-key.pem --skipApiVersionCheck -d D:\azurite\debug.log

Certificate is valid and I am able to use Azure Storage Explorer to connect and view the files in the instance

Using the Azure.Storage.Blobs SDK version 12.20.0, I have code like this:

UserDelegationKey key = await _blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddMinutes(5));
BlobSasBuilder sasBuilder = new()
{
    BlobContainerName = containerName,
    BlobName = fileName,
    Resource = "b",
    StartsOn = DateTimeOffset.UtcNow,
    ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(5)
};

sasBuilder.SetPermissions(BlobSasPermissions.Read);

string link = $"{_blobServiceUri}{containerName}/{fileName}?{sasBuilder.ToSasQueryParameters(key, _options.AccountName)}";

Generates a link that looks like this:

https://127.0.0.1:10000/devstoreaccount1/0cd6b12f-2c13-4953-9b13-33fa412d9733/test.png?skt=2024-06-11T16%3A02%3A10Z&ske=2024-06-11T16%3A07%3A10Z&sks=b&skv=2023-11-03&sv=2024-05-04&st=2024-06-11T16%3A02%3A12Z&se=2024-06-11T16%3A07%3A12Z&sr=b&sp=r&sig=lbKCvP0XQ4avTPVi%2FPIea8h3SByi6NBFgm8PqjF436Y%3D

When connected to Azurite, I get a 403 back. Connected to a real storage account, the file downloads as expected (confirmed in an incognito browser window).

I attached the debug.log, looks like it fails on validating the UDK?

azurite-debug.log

Have you found a mitigation/solution?

No, nothing I have done locally seems to work.

blueww commented 2 weeks ago

@danjohnso

Thanks for reporting this issue! From the debug log, the error is signature calculated from Azurite code is not aligned with the signature in the SAS.

I can repro it. I have looked into the stringToSign of Azurite and the one on real Azure server, they have same structure (except account name). The delegation key is also correct per my testing. Not sure why the signature not match.

I will need more time to debug into SDK code to see what's the real stringTosign SDK use. And compare it with Azurite Code generated one.

blueww commented 2 weeks ago

@EmmaZhu

Could you please help to look at the user delegation SAS failure? Thanks!

EmmaZhu commented 2 weeks ago

Hi @danjohnso

Could you share how you get the _blobServiceClient instance? Service side token credentials may not work for Azurite.

danjohnso commented 2 weeks ago
_blobServiceClient = new BlobServiceClient(_options.ServiceUri, new DefaultAzureCredential());

ServiceUri is "https://127.0.0.1:10000/devstoreaccount1/" for Azurite, real connection is "https://ACCOUNT_NAME.blob.core.windows.net/"

danjohnso commented 2 weeks ago

Did a little more testing, maybe this is an issue with the SDK.... If I use Azure Storage Explorer, I can generate the token and it works. This is the example generated url:

https://127.0.0.1:10000/devstoreaccount1/0cd6b12f-2c13-4953-9b13-33fa412d9733/test2.png?sv=2018-03-28&st=2024-06-12T14%3A54%3A49Z&se=2024-06-13T14%3A54%3A49Z&sr=b&sp=r&sig=LXc787p4kHXJ8sw%2FaBblbHRLCA38Brw%2BFBDu9rqcLm8%3D

I notice there are less querystring params in this generated URL as compared to the SDK generated one.

EmmaZhu commented 2 weeks ago

Hi @danjohnso ,

The URL you generated by Azure Storage Explorer seems generated by storage key credential instead of OAuth. It doesn't include delegation SAS required query values.