0
votes

I have a problem, which I cannot figure out to solve:

Our company has appr. 20 Azure storage accounts with appr. 20 containers each. I want to write a .NET Core console application, which I can run on a (non-Azure) Windows server for backing up the blobs with read-only access to a (non-Azure) server.

If I would use the storage access keys, I would have the problems a) I would need 20 different access keys and b) the access keys allow for full access, which I don't want to grant this console application for security reasons. Using an authentication with SAS, even worse, I would have appr. 400 different SAS keys (20 storage accounts x 20 containers).

Now: On Azure, I created a new user, e. g. "[email protected]", which is a global reader - so no possibility to write/delete, which would satisfy the security issues. I registered my application as a Windows application.

However, despite reading and trying out so many ways, I was not able to figure out how my console application can automatically log in through e. g. Azure Active Directory (password) with the username + password of [email protected]. It would also be important to store username/password e. g. in appsettings.json).

Can you provide .NET Core C# code how I can a) login and b) list all blobs in one storage account >> container?

Thanks so much!!

Martin

1

1 Answers

0
votes

According to your need, I suggest you use Azure AD auth to access Azure Blob. If you use the way, we need to assgin Storage Blob Data Reader to the user or service principal. After that, the user or service principal has permission to list containers and blobs. For more details, please refer to here and here

For example

  1. Create a service principal and assign Storage Blob Data Reader role to the sp
az login

# assign role at the description level the sp can manage all storage account in the subscription
az ad sp create-for-rbac -n "ManageStorage" --role "Storage Blob Data Reader"

enter image description here

  1. Set environmental variables
setx AZURE_CLIENT_ID <your-clientID>

setx AZURE_CLIENT_SECRET <your-clientSecret>

setx AZURE_TENANT_ID <your-tenantId>
  1. Application

a. sdk

<PackageReference Include="Azure.Identity" Version="1.1.1" />
    <PackageReference Include="Azure.Storage.Blobs" Version="12.4.4" />

b. Code

            string accountName = "jimtestdiag417";
            string url = string.Format("https://{0}.blob.core.windows.net/", accountName);
            var account = new BlobServiceClient(new Uri(url), new DefaultAzureCredential());
            string containerContinuationToken = null;
            int pageSizeHint = 5; //The size of Page<T>s that should be requested 
            // list conatnies in the storage account
            do
            {
                var containerResultSegment = account.GetBlobContainersAsync().AsPages(containerContinuationToken, pageSizeHint);
                await foreach (Page<BlobContainerItem> containerPage in containerResultSegment) {

                    foreach (var container in containerPage.Values) {

                        Console.WriteLine( string.Format("The blobs in the container {0} are as follows ", container.Name));
                        string blobContinuationToken = null;
                        // list blobs in the container
                        do
                        {

                            var blobResultSegment = account.GetBlobContainerClient(container.Name).GetBlobsAsync().AsPages(blobContinuationToken, pageSizeHint);
                            await foreach (Page<BlobItem> blobPage in blobResultSegment)
                            {

                                foreach (var blob in blobPage.Values)
                                {
                                       Console.WriteLine(blob.Name);
                                    
                                }

                            }
                        } while (blobContinuationToken != null);

                       
                    }
                }
            } while (containerContinuationToken != null);

enter image description here