Azure Storage is a service that allows you to store files (among other things) in the Azure cloud from your applications. To connect to it, you can use many methods; the most practical is to use a connection string, which gives full permissions to the storage operations. And full permissions on anything are not optimal or secure. In this post, I will show you how you can connect to Azure Storage through Token Credentials coupled with Azure RBAC support. Let’s begin.
1. Create an Azure AD service principal that can connect to Azure Storage API
RBAC access properties can be defined on Users, Groups, or Service Principals (we will skip managed identity in this post). We can create a service principal in Azure AD that is an identity that can authenticate to our Azure Storage account. To access the target service (in our case Azure Storage), the service principal needs an assigned role.
- Go to the Azure portal and navigate to your Azure Active Directory.
- Go to App Registrations in the sidebar menu and click + New registration.
- Type the name of the application and click Register (figure 1).
- Next, create a secret for the application by clicking Certificates & Secrets from the sidebar menu, then click + New client secret, specify the name and click Add button (figure 2).
- Copy the secret value because you can only see it once. Once you leave the page, you’ll need to regenerate it (figure 3).
- Copy the Application ID and Directory ID to the notepad (figure 4).
- Copy the Authorization Endpoint to notepad (figure 5).
2. Add the role to a service principal on the Azure Storage
I did not write step-by-step instructions here on how to create a new instance of Azure Storage. Now let’s add the RBAC role to the service principal we created above. For this demo, we will assign a Storage Blob Data Contributor role, adding a read, write and delete access to the service principal.
- Open your Azure Storage account and click on Access Control (IAM) in the sidebar menu. Then click on the + Add button and Add role assignment (figure 6).
- Then select the Storage Blob Data Contributor role from the list and click Next (figure 7).
- Find the service principal we created above by name and Review & assign it (figure 8).
- Create a blob container named demo in your Azure Storage account, which will be used in the C# sample below.
3. C# snippet to upload blob with service principal through TokenCredential
Below is a code snippet to connect to the Azure Storage with Token Credentials that we get from the Authorization Endpoint of our Azure AD. Use your values from the notepad you stored above to replace the placeholders.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
using System.Text; using Azure.Core; using Azure.Identity; using Azure.Storage.Blobs; namespace AzureStorage { internal class Program { static async Task Main(string[] args) { Uri blobUri = new Uri("https://<mystoragename>.blob.core.windows.net/"); TokenCredential credential = new ClientSecretCredential( "<DirectoryID>", "<ApplicationID>", "<ApplicationSecret>", new TokenCredentialOptions() { AuthorityHost = new Uri("<Authorization Endpoint>") }); var blobServiceClient = new BlobServiceClient(blobUri, credential); var containerClient = blobServiceClient.GetBlobContainerClient("demo"); await containerClient.UploadBlobAsync("BlobFile.txt", new BinaryData(Encoding.ASCII.GetBytes("This is the content of the file."))); Console.WriteLine("Done."); } } } |
And this is how you can replace your Azure Storage Connection string with Service Principal through Token Credentials. Why is this better?
- With the Service principal, you can define roles through the Azure AD RBAC system. Some of your applications can only have read permissions, and others read, write and delete, etc. No more full permissions to applications connecting to your services.
- You can easily block access of a specific application to the Azure storage by disabling the service principal and leaving other applications to work as usual.
- Separation of concerns where Azure AD administrators, on the one hand, can set up the service principal and its roles and permissions, and developers, on the other hand, can use that information to integrate it into the application.
- Let me know if you can think of more :).