Introduction Azure Storage:
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.
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.
To get Directory/ Tenant Id.
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.
- static string GetUserOAuthToken(string tenantId, string applicationId, string clientSecret)
- {
- const string ResourceId = "https://storage.azure.com/";
- const string AuthInstance = "https://login.microsoftonline.com/{0}/";
- string authority = string.Format(CultureInfo.InvariantCulture, AuthInstance, tenantId);
- AuthenticationContext authContext = new AuthenticationContext(authority);
- var clientCred = new ClientCredential(applicationId, clientSecret);
- AuthenticationResult result = authContext.AcquireTokenAsync(
- ResourceId,
- clientCred
- ).Result;
- return result.AccessToken;
- }
File Upload and Download Methods
- public static class AzureOperations {
- #region ConfigParams
- public static string tenantId;
- public static string applicationId;
- public static string clientSecret;
- #endregion
- public static void UploadFile(AzureOperationHelper azureOperationHelper) {
- CloudBlobContainer blobContainer = CreateCloudBlobContainer(tenantId, applicationId, clientSecret, azureOperationHelper.storageAccountName, azureOperationHelper.containerName, azureOperationHelper.storageEndPoint);
- blobContainer.CreateIfNotExists();
- CloudBlockBlob blob = blobContainer.GetBlockBlobReference(azureOperationHelper.blobName);
- blob.UploadFromFile(azureOperationHelper.srcPath);
- }
- public static void DownloadFile(AzureOperationHelper azureOperationHelper) {
- CloudBlobContainer blobContainer = CreateCloudBlobContainer(tenantId, applicationId, clientSecret, azureOperationHelper.storageAccountName, azureOperationHelper.containerName, azureOperationHelper.storageEndPoint);
- CloudBlockBlob blob = blobContainer.GetBlockBlobReference(azureOperationHelper.blobName);
- blob.DownloadToFile(azureOperationHelper.destinationPath, FileMode.OpenOrCreate);
- }
- private static CloudBlobContainer CreateCloudBlobContainer(string tenantId, string applicationId, string clientSecret, string storageAccountName, string containerName, string storageEndPoint) {
- string accessToken = GetUserOAuthToken(tenantId, applicationId, clientSecret);
- TokenCredential tokenCredential = new TokenCredential(accessToken);
- StorageCredentials storageCredentials = new StorageCredentials(tokenCredential);
- CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(storageCredentials, storageAccountName, storageEndPoint, useHttps: true);
- CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient();
- CloudBlobContainer blobContainer = blobClient.GetContainerReference(containerName);
- return blobContainer;
- }
- static string GetUserOAuthToken(string tenantId, string applicationId, string clientSecret) {
- const string ResourceId = "https://storage.azure.com/";
- const string AuthInstance = "https://login.microsoftonline.com/{0}/";
- string authority = string.Format(CultureInfo.InvariantCulture, AuthInstance, tenantId);
- AuthenticationContext authContext = new AuthenticationContext(authority);
- var clientCred = new ClientCredential(applicationId, clientSecret);
- AuthenticationResult result = authContext.AcquireTokenAsync(ResourceId, clientCred).Result;
- return result.AccessToken;
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- // Set Ids of your Azure account
- AzureOperations.applicationId = "";
- AzureOperations.clientSecret = "";
- AzureOperations.tenantId = "";
- //Demo Upload File
- string srcPathToUpload = string.Format(@"C:\Users\abdul.rehman\Desktop\AzureFileUpload\myfile.txt");
- UploadFile(srcPathToUpload);
- //Demo Download File
- string azurePathInBlob = "dev/files/myfile.txt";
- string destinationPath= string.Format(@"C:\Users\abdul.rehman\Desktop\AzureFileDownload\myfile.txt");
- DownloadFile(destinationPath, azurePathInBlob);
- }
- public static void UploadFile(string srcPath)
- {
- AzureOperationHelper azureOperationHelper = new AzureOperationHelper();
- // your Storage Account Name
- azureOperationHelper.storageAccountName = "dbpoc";
- azureOperationHelper.storageEndPoint = "core.windows.net";
- // File path to upload
- azureOperationHelper.srcPath = srcPath;
- // Your Container Name
- azureOperationHelper.containerName = "filecontainer";
- // Destination Path you can set it file name or if you want to put it in folders do it like below
- azureOperationHelper.blobName = string.Format("dev/files/" + Path.GetFileName(srcPath));
- AzureOperations.UploadFile(azureOperationHelper);
- }
- public static void DownloadFile(string destinationPath, string srcPath)
- {
- AzureOperationHelper azureOperationHelper = new AzureOperationHelper();
- // your Storage Account Name
- azureOperationHelper.storageAccountName = "dbpoc";
- azureOperationHelper.storageEndPoint = "core.windows.net";
- // Destination Path where you want to download file
- azureOperationHelper.destinationPath = destinationPath;
- // Your Container Name
- azureOperationHelper.containerName = "filecontainer";
- // Blob Path in container where to download File
- azureOperationHelper.blobName = srcPath;
- AzureOperations.DownloadFile(azureOperationHelper);
- }
- }
NuGet Dependencies
- WindowsAzure.Storage (I have installed v9.3.3).
- Microsoft.IdentityModel.Clients.ActiveDirectory (I have installed v4.4.2).
- 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.
- Permissions are very critical. Your application role must have read/write/delete permissions on Blob Management and Data as well.
No comments:
Post a Comment