ChipperDiglett
ChipperDiglett

Reputation: 45

Trouble downloading azure storage blobs under private access in c#

I'm a complete noob at c# and know very little about azure apis and a current cs student doing a project for work. I built some middleware with youtube tutorials that authenticates a with a storage account using a string connection and it enumerates, uploads, downloads, and deletes blobs within a container. The issue i'm having lies with ONLY the downloading functionality and ONLY when the storage account access is set to private. This function works fine with anon access. I suspect the issue is with appending the url, and I'm not sure how to fix it. The blobs are mainly csv data if that matters. Any help or direction to resources would be greatly appreciated 🙂 here is the relevant code:

url function

public async Task<string> GetBlob(string name, string containerName)
    {
        var containerClient = _blobClient.GetBlobContainerClient(containerName);
        var blobClient = containerClient.GetBlobClient(name);
        return blobClient.Uri.AbsoluteUri;

    }

The config file

  "AllowedHosts": "*",
  "BlobConnection" : "<mystringconnection>******==;EndpointSuffix=core.windows.net"

action request

[HttpGet]
    public async Task<IActionResult> ViewFile(string name)
    {
        var res = await _blobService.GetBlob(name, "<mystorageacc>");
        return Redirect(res);
    }

Upvotes: 2

Views: 2582

Answers (3)

Naveed
Naveed

Reputation: 11

This worked for me by returning a byte array:

byte[] base64ImageRepresentation = new byte[] { };

BlobClient blobClient = new BlobClient(blobConnectionString,
    blobContainerUserDocs,+ "/" + fileName);

if (await blobClient.ExistsAsync())
{
    using var ms = new MemoryStream();
    await blobClient.DownloadToAsync(ms);
    return ms.ToArray();
}

Upvotes: 0

Gaurav Mantri
Gaurav Mantri

Reputation: 136216

The reason you are not able to download the blobs from a private container is because you are simply returning the blob's URL from your method without any authorization information. Request to access blobs in a private container must be authorized.

What you would need to do is create a Shared Access Signature (SAS) with at least Read permission and then return that SAS URL. The method you would want to use is GenerateSasUri. Your code would be something like:

public async Task<string> GetBlob(string name, string containerName)
{
    var containerClient = _blobClient.GetBlobContainerClient(containerName);
    var blobClient = containerClient.GetBlobClient(name);
    return blobClient.GenerateSasUri(BlobSasPermissions.Read, DateTime.UtcNow.AddMinutes(5)).Uri.AbsoluteUri;
}

This will give you a link which is valid for 5 minutes from the time of creation and has the permission to read (download) the blob.

Upvotes: 1

dcansyn
dcansyn

Reputation: 106

If you want to download from the blob service;

    public async Task<byte[]> ReadFileAsync(string path)
    {
        using var ms = new MemoryStream();
        var blob = _client.GetBlobClient(path);
        await blob.DownloadToAsync(ms);
        return ms.ToArray();
    }

If you want to download the file byte array from controllers, you can check this; https://stackoverflow.com/a/3605510/3024129

If you want to set a blob file public access level; https://learn.microsoft.com/en-us/azure/storage/blobs/anonymous-read-access-configure.

Pay attention to the images please;

enter image description here

Or you can connect with Azure Storage Explorer and choose the easy way.

enter image description here enter image description here

I found the images on the Google, there may be differences. :)

Upvotes: 0

Related Questions