I am using a SAS token to access Azure Blob Store using the c# API. I can successfully create new blobs in a container and, given the name of a blob, I can read that blob and get the contents. However, I am unable to LIST the blobs in the container as I get an InvalidURl error: The requested URI does not represent any resource on the server.
I am using the same sas URI for all three requests, upload, download, and list.
I generate the sas URI using the following code:
if (containerClient.CanGenerateSasUri)
{
BlobSasBuilder sasBuilder = new BlobSasBuilder()
{
BlobContainerName = containerClient.Name,
Resource = "c"
};
if (storedPolicyName == null)
{
sasBuilder.ExpiresOn = DateTimeOffset.UtcNow.AddHours(1);
sasBuilder.SetPermissions(BlobContainerSasPermissions.All);
}
else
{
sasBuilder.Identifier = storedPolicyName;
}
Uri sasUri = containerClient.GenerateSasUri(sasBuilder);
}
And I attempt to list the names of the blobs using the folowing code:
var serviceClient = new BlobServiceClient(sasUri);
var containerClient = serviceClient.GetBlobContainerClient(container);
var blobs = containerClient.GetBlobsByHierarchyAsync();
await foreach (var blob in blobs)
{
if (blob.IsBlob)
{
blobNames.Add(blob.Blob.Name);
}
}
If I create the BlobServiceClient using the connection string (rather than a sas URI), then this code works and can list the blobs that I have uploaded using the sas URI, but using the sas URI fails with InvalidURL (even though is the same sas token that I just used to create the blob in the container and it has permissions to list blobs in the container).
If I hard code a known filename I can use the sas containerClient to create a working BlobClient:
var blobClient = containerClient.GetBlobClient("blobname");
if (await blobClient.ExistsAsync())
{
var stream = await blobClient.DownloadStreamingAsync();
return stream.Value.Content;
}
What do I need to do to get the List operation to work with the sas token? Any pointers to what I'm missing greatly appreciated!
CodePudding user response:
The reason you are running into issues is because you are using a Blob Container SAS URI to create BlobServiceClient
and when you create a BlobContainerClient instance using the service client, the container name is repeated twice.
Possible solutions:
- Directly create an instance of
BlobContainerClient
using the container SAS URL. You can do something like:
containerClient = new BlobContainerClient(sasUri);
- Create an instance of
BlobServiceClient
using just the SAS token (and not SAS URL) and account endpoint. You can do something like:
var endpoint = $"{uri.Scheme}://{uri.Host}";
var sasToken = uri.Query;
var credentials = new AzureSasCredential(sasToken);
var serviceClient = new BlobServiceClient(new Uri(endpoint), credentials);
var containerClient = serviceClient.GetBlobContainerClient(container);
...
...rest of your code
...