0
votes

I'm trying to get a Blob Stream from a private Storage Container in Azure. I got some help on the internet from a few places to come up with this function:

/// <summary>
/// Get a blob out of storage.
/// HEAVILY Based on Code from:
/// https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-customer-provided-key
/// </summary>
/// <param name="iSA">Name of storage account</param>
/// <param name="iSA_Key">Key for the storage account</param>
/// <param name="iContainerName">Name of the container</param>
/// <param name="iBlobName">Name of Blob to Get</param>
/// <returns>
/// A stream of the Blob
/// </returns>
public Stream getBlob(
    String iSA, String iSA_Key, String iContainerName,
    String iBlobName)
{
    Uri accountUri = new Uri("https://" + iSA + ".blob.core.windows.net");

    // https://stackguides.com/questions/16072709/converting-string-to-byte-array-in-c-sharp
    byte[] key = Encoding.ASCII.GetBytes(iSA_Key);

    // Specify the customer-provided key on the options for the client.
    BlobClientOptions options = new BlobClientOptions()
    {
        CustomerProvidedKey = new CustomerProvidedKey(key)
    };

    // Create a client object for the Blob service, including options.
    BlobServiceClient serviceClient = new BlobServiceClient(accountUri,
        new DefaultAzureCredential(), options);

    // Create a client object for the container.
    // The container client retains the credential and client options.
    BlobContainerClient containerClient = serviceClient.GetBlobContainerClient(iContainerName);

    // Create a new block blob client object.
    // The blob client retains the credential and client options.
    BlobClient blobClient = containerClient.GetBlobClient(iBlobName);

    Azure.Response<BlobDownloadInfo> myAR = blobClient.Download();

    BlobDownloadInfo BDI = myAR.Value;
    return BDI.Content;
}

Unfortunately, it's giving me the following error when I call blobClient.Download():
Azure.RequestFailedException: 'This request is not authorized to perform this operation using this permission...'

Is there something easy I can fix with this?

AFAIK: I am passing the correct parameters into the function...

1
The Microsoft article I cited seems to be about encryption keys. Maybe not about storage keys...Shawn Eary

1 Answers

1
votes

Not sure if I got all of the MIME stuff right; however, as stated in my comment, the Microsoft example was about how to supply a customer Encryption Key. It was not about how to supply the Storage Key. I looked around at bit and played in the IDE and was able to create a StorageSharedKeyCredential that I could pass into the BlobServiceClient constructor with a slight modification to the original Microsoft example:

/// <summary>
/// Get a blob out of storage.
/// HEAVILY Based on Code from:
/// https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-customer-provided-key
/// </summary>
/// <param name="iSA">Name of storage account</param>
/// <param name="iSA_Key">Key for the storage account</param>
/// <param name="iContainerName">Name of the container</param>
/// <param name="iBlobName">Name of Blob to Get</param>
/// <returns>
/// A stream of the Blob
/// </returns>
public Stream getBlob(
    String iSA, String iSA_Key, String iContainerName,
    String iBlobName)
{
    Uri accountUri = new Uri("https://" + iSA + ".blob.core.windows.net");

    // Create a client object for the Blob service
    // https://docs.microsoft.com/en-us/dotnet/api/azure.storage.storagesharedkeycredential?view=azure-dotnet
    StorageSharedKeyCredential SSKC = new StorageSharedKeyCredential(iSA, iSA_Key);
    BlobServiceClient serviceClient = new BlobServiceClient(accountUri, SSKC);

    // Create a client object for the container.
    // The container client retains the credential and client options.
    BlobContainerClient containerClient = serviceClient.GetBlobContainerClient(iContainerName);

    // Create a new block blob client object.
    // The blob client retains the credential and client options.
    BlobClient blobClient = containerClient.GetBlobClient(iBlobName);

    Azure.Response<BlobDownloadInfo> myAR = blobClient.Download();

    BlobDownloadInfo BDI = myAR.Value;
    return BDI.Content;
}

I am at least getting a usable file stream back from the Storage Account now.