Upload And Download File To Azure Blob Storage Using C#

Introduction

Azure Storage is a service provided by Microsoft to store the data, such as text or binary. You can use this data to make it available to the public or secure it from public access. There are multiple ways I found on the internet to upload the content to Azure Blob Storage, like you can use shared keys, or use a Connection string, or a native app.

Problem

Now, here is the problem. Suppose you have to create a Windows Service which will upload and download your files to the Azure Blob Storage. And as per the requirements, you don’t have to use a shared key or connection string or simply your client didn’t share it. The client wants to get it done by Active Directory Authentication. With the Native app, as most of the samples over the internet, the user consent is required if your token expires and that’s why it cannot be used in Windows Service.

Solution

After spending some time on it, I found the right way to upload and download a file on Azure Blob Storage. As I didn’t find any documentation or samples particular to this requirement over the internet, I am sharing it. Hope it will help.

Create an application on Azure

Create an application of Web app/API type on the Azure portal.

 Upload And Download File To Azure Blob Storage Using C#
 

Get Keys for Authentication

You need to have the application id, tenant/Directory Id, and Client Secret key.

After application creation, you will see the below screen where you have the application Id and from the Keys section, you can generate Client Secret key. See the below screens.

 Upload And Download File To Azure Blob Storage Using C#

To get Directory/ Tenant Id.

 Upload And Download File To Azure Blob Storage Using C#

 Upload And Download File To Azure Blob Storage Using C#

Role assignment to your Azure application

Now, go to your storage account that you want to use and assign your application Storage Blob Data Owner/Contributor Role.

 Upload And Download File To Azure Blob Storage Using C#
 
Upload And Download File To Azure Blob Storage Using C#
 
Actually, the above role gives you permissions to read/write/delete on Blob Management and Data. With Management permission, you can read/write/delete a container in the Blob and with Data, you can read/write/delete content in it.
 
Upload And Download File To Azure Blob Storage Using C#
 
Now, you have all the things you need to build an application. Let's see the code snippets.
 
Authentication
 
The first thing you need is to get an access token and you can get it using the below method.
  1. static string GetUserOAuthToken(string tenantId, string applicationId, string clientSecret)  
  2.         {  
  3.             const string ResourceId = "https://storage.azure.com/";  
  4.             const string AuthInstance = "https://login.microsoftonline.com/{0}/";  
  5.   
  6.             string authority = string.Format(CultureInfo.InvariantCulture, AuthInstance, tenantId);  
  7.             AuthenticationContext authContext = new AuthenticationContext(authority);  
  8.   
  9.             var clientCred = new ClientCredential(applicationId, clientSecret);  
  10.             AuthenticationResult result = authContext.AcquireTokenAsync(  
  11.                                                 ResourceId,  
  12.                                                 clientCred  
  13.                                                 ).Result;  
  14.             return result.AccessToken;  
  15.         }     

File Upload and Download Methods

Below is the code snippet to upload and download the file to Azure Blob Storage.
  1. public static class AzureOperations {  
  2.     #region ConfigParams  
  3.     public static string tenantId;  
  4.     public static string applicationId;  
  5.     public static string clientSecret;  
  6.     #endregion  
  7.     public static void UploadFile(AzureOperationHelper azureOperationHelper) {  
  8.         CloudBlobContainer blobContainer = CreateCloudBlobContainer(tenantId, applicationId, clientSecret, azureOperationHelper.storageAccountName, azureOperationHelper.containerName, azureOperationHelper.storageEndPoint);  
  9.         blobContainer.CreateIfNotExists();  
  10.         CloudBlockBlob blob = blobContainer.GetBlockBlobReference(azureOperationHelper.blobName);  
  11.         blob.UploadFromFile(azureOperationHelper.srcPath);  
  12.     }  
  13.     public static void DownloadFile(AzureOperationHelper azureOperationHelper) {  
  14.         CloudBlobContainer blobContainer = CreateCloudBlobContainer(tenantId, applicationId, clientSecret, azureOperationHelper.storageAccountName, azureOperationHelper.containerName, azureOperationHelper.storageEndPoint);  
  15.         CloudBlockBlob blob = blobContainer.GetBlockBlobReference(azureOperationHelper.blobName);  
  16.         blob.DownloadToFile(azureOperationHelper.destinationPath, FileMode.OpenOrCreate);  
  17.     }  
  18.     private static CloudBlobContainer CreateCloudBlobContainer(string tenantId, string applicationId, string clientSecret, string storageAccountName, string containerName, string storageEndPoint) {  
  19.         string accessToken = GetUserOAuthToken(tenantId, applicationId, clientSecret);  
  20.         TokenCredential tokenCredential = new TokenCredential(accessToken);  
  21.         StorageCredentials storageCredentials = new StorageCredentials(tokenCredential);  
  22.         CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(storageCredentials, storageAccountName, storageEndPoint, useHttps: true);  
  23.         CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient();  
  24.         CloudBlobContainer blobContainer = blobClient.GetContainerReference(containerName);  
  25.         return blobContainer;  
  26.     }  
  27.     static string GetUserOAuthToken(string tenantId, string applicationId, string clientSecret) {  
  28.         const string ResourceId = "https://storage.azure.com/";  
  29.         const string AuthInstance = "https://login.microsoftonline.com/{0}/";  
  30.         string authority = string.Format(CultureInfo.InvariantCulture, AuthInstance, tenantId);  
  31.         AuthenticationContext authContext = new AuthenticationContext(authority);  
  32.         var clientCred = new ClientCredential(applicationId, clientSecret);  
  33.         AuthenticationResult result = authContext.AcquireTokenAsync(ResourceId, clientCred).Result;  
  34.         return result.AccessToken;  
  35.     }  
  36. }  
Test it in a Console application.
  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             // Set Ids of your Azure account  
  6.             AzureOperations.applicationId = "";  
  7.             AzureOperations.clientSecret = "";  
  8.             AzureOperations.tenantId = "";  
  9.   
  10.             //Demo Upload File  
  11.             string srcPathToUpload = string.Format(@"C:\Users\abdul.rehman\Desktop\AzureFileUpload\myfile.txt");              
  12.             UploadFile(srcPathToUpload);  
  13.   
  14.   
  15.             //Demo Download File  
  16.             string azurePathInBlob = "dev/files/myfile.txt";  
  17.             string destinationPath= string.Format(@"C:\Users\abdul.rehman\Desktop\AzureFileDownload\myfile.txt");  
  18.             DownloadFile(destinationPath, azurePathInBlob);  
  19.   
  20.         }  
  21.   
  22.         public static void UploadFile(string srcPath)  
  23.         {              
  24.             AzureOperationHelper azureOperationHelper = new AzureOperationHelper();  
  25.             // your Storage Account Name  
  26.             azureOperationHelper.storageAccountName = "dbpoc";  
  27.             azureOperationHelper.storageEndPoint = "core.windows.net";  
  28.             // File path to upload  
  29.             azureOperationHelper.srcPath = srcPath;   
  30.             // Your Container Name   
  31.             azureOperationHelper.containerName = "filecontainer";   
  32.             // Destination Path you can set it file name or if you want to put it in folders do it like below  
  33.             azureOperationHelper.blobName = string.Format("dev/files/" + Path.GetFileName(srcPath));   
  34.             AzureOperations.UploadFile(azureOperationHelper);  
  35.   
  36.         }  
  37.   
  38.         public static void DownloadFile(string destinationPath, string srcPath)  
  39.         {             
  40.             AzureOperationHelper azureOperationHelper = new AzureOperationHelper();  
  41.             // your Storage Account Name  
  42.             azureOperationHelper.storageAccountName = "dbpoc";  
  43.             azureOperationHelper.storageEndPoint = "core.windows.net";  
  44.             // Destination Path where you want to download file  
  45.             azureOperationHelper.destinationPath = destinationPath;  
  46.             // Your Container Name   
  47.             azureOperationHelper.containerName = "filecontainer";  
  48.             // Blob Path in container where to download File  
  49.             azureOperationHelper.blobName = srcPath;  
  50.               
  51.             AzureOperations.DownloadFile(azureOperationHelper);  
  52.   
  53.         }         
  54.     }  

NuGet Dependencies

  1. WindowsAzure.Storage (I have installed v9.3.3).
  2. Microsoft.IdentityModel.Clients.ActiveDirectory (I have installed v4.4.2).
There are a few things you need to check. 
  1. Container name should be in lowercase. I don't know why it is not handled but in this version, it is not working with uppercase.
  2. Permissions are very critical. Your application role must have read/write/delete permissions on Blob Management and Data as well.  

Summary

 
In this above sample, we learned how to manage our files on Azure Blob Storage with Active Directory Authentication using the application Secret Key. And like Native app, no popup will be shown to enter the credentials in order to get the access token.
 
I have also uploaded the sample console application that you can download and test with your Azure credentials. Feel free to contact me in case of an issue.
 
 
References
 
https://docs.microsoft.com/en-us/azure/storage/blobs/storage-upload-process-images?tabs=dotnet 
https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-dotnet?tabs=windows