ASP.NET web app- ConfigurationBuilder in a web app to retrieve access keys

In this tutorial, you configure an existing ASP.NET web app to retrieve sensitive information, such as connection strings, from your Azure key vault. By using Azure Key Vault, you help protect security information that could otherwise be used by a malicious application to attack your system.

The scenario in this module involves an existing .NET Framework web app that runs on-premises. You start by migrating this application to a web app that’s built by using Azure App Service. Next, you store the secrets that are required by this application to connect to resources such as a database in your key vault. Finally, you configure the application by using a ConfigurationBuilder object that retrieves information from the key vault.

Use the ConfigurationBuilder type

Configuring the app is central to building it in a way that allows its dependencies to vary, based on the environment in which it’s deployed. In .NET Framework apps, the most common mechanism to customize app configuration is through the ConfigurationManager type. You can use a configuration manager to read settings that are often stored in the app.config file for desktop apps, or in the web.config file for ASP.NET web apps.

dot net

One of the challenges with storing configuration settings in this manner is that values to be kept secret often end up being stored as plain text somewhere. This practice creates a security vulnerability. You use the ConfigurationBuilder class to remove this vulnerability.

What is the ConfigurationBuilder class?

The ConfigurationManager approach that’s used by many traditional .NET Framework and ASP.NET web apps allows an administrator to store configuration information as a series of keys and values in a config file. ConfigurationManager has been the primary mechanism to avoid hard-wiring information into an app, and it’s well understood by most ASP.NET developers.

The simplicity of using ConfigurationManager can also be a significant shortcoming. It’s not easy to store and retrieve configuration information in sources other than the config file that’s associated with the app. Large-scale enterprise systems, especially those running in the cloud, frequently need to adapt their configuration dynamically, and they require other sources of configuration information.

Additionally, the config file that’s used by ConfigurationManager is typically held as plain text, although some encryption options are available. Encryption can be cumbersome, and it still requires an encryption key to be stored somewhere. Hard-coding the encryption key in app code isn’t a secure solution, even after the app is compiled. A determined attacker could disassemble your code and read the key. These issues can make using ConfigurationManager an unsuitable mechanism for storing sensitive configuration information, such as passwords and connection strings, unless a great deal of care is taken.

A ConfigurationBuilder object is designed to enable you to retrieve configuration information from a variety of sources.

The ConfigurationBuilder mechanism is an extension of the concepts implemented by the ConfigurationManager class. Rather than restricting configuration information to a strict XML grammar stored in a text file, you can use a variety of configuration builders, based on different configuration sources. A configuration builder provides its own specific means to access data. Currently available configuration builders include:

  • Microsoft.Configuration.ConfigurationBuilders.Environment: Adds settings from the environment variables of the current process
  • Microsoft.Configuration.ConfigurationBuilders.UserSecrets: Adds user secrets contained in an XML file external to the code base
  • Microsoft.Configuration.ConfigurationBuilders.Azure: Pulls items from key vault
  • Microsoft.Configuration.ConfigurationBuilders.KeyPerFile: File based, where the name of the file is the key, and the contents are the value
  • Microsoft.Configuration.ConfigurationBuilders.Json: Pulls key/value pairs from JSON files

You can also create your own custom ConfigurationBuilder class if you need to access configuration information that’s held in store and for which no builder is currently available.

The choice as to which configuration builder to use depends on the scenarios and the requirements of an individual app.

How ConfigurationBuilder objects work

An app reads information from a configuration builder object in exactly the same way as it would have previously, by using a ConfigurationManager object. You can continue to use the ConfigurationManager.AppSettings[“settingName”] idiom, and you don’t need to change your app code.

Instead, you provide the details of the configuration builders to use in the app config file on cloud or hosting. You specify which builders to apply to retrieve app settings and connection strings by using the configBuilders attribute of the appSettings and connectionStrings sections in the app config file.

You add ConfigurationBuilder types to the <configBuilders> section in the config. Each builder you add is assigned a name (a string that’s used to reference the builder from elsewhere in the config), and the full type name. Many builders take additional, builder-specific parameters. You also need to add the assembly that processes the <configBuilders> section.

The following example adds the builders for using environment variables and user secrets. The userSecretsId parameter indicates the identity of the user secret that contains the data. At runtime, the builder looks in the secrets.xml file, which is stored in a protected location (%APPDATA%\Microsoft\UserSecrets<userSecretsId>\secrets.xml in Windows), for the value to use:

<configuration>
  <configSections>
    <section name="configBuilders" type="System.Configuration.ConfigurationBuildersSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false" />
    ...
  </configSections>
  <configBuilders>
    <builders>
      <add name="Environment" type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.Environment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      <add name="Secrets" userSecretsId="c96e0578-6490-4a2d-b6c5-cb2b0baaeae8" type="Microsoft.Configuration.ConfigurationBuilders.UserSecretsConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.UserSecrets, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </builders>
  </configBuilders>
  <appSettings configBuilders="Environment,Secrets">
    <add key="MySecretData" value="" />
    <add key="MyEnvironmentData" value="" />
  </appSettings>
  ...
<configuration>

In this example, when an app retrieves the value of the MySecretData key or the MyEnvironmentData key, the configuration entry is composed of values from the specified sources. The values are listed in the order in which they are stated. Here, entries from Environment are added first, followed by those from Secrets. This means that the last source that has a specified value is surfaced to the user. You can change the search order by switching the sequence in the configBuilders attribute.

Configuration is central to building an app in a way that allows its dependencies to vary, based on the environment in which it’s deployed.

In this post, you learned:

The purpose of the ConfigurationBuilder mechanism, which is to help avoid storing sensitive configuration information in easily accessible locations.
How to use ConfigurationBuilder in a web app to retrieve access keys from your Azure key vault at runtime.

When you’re working in your own subscription, it’s a good idea at the end of a project to identify whether you still need the resources you created. Resources left running can cost you money. You can delete resources individually or delete the resource group to delete the entire set of resources.

Create Azure Batch workloads from .NET app

Azure Batch is a collection of resources you combine together to produce a large-scale parallel, highly performant solution.

You decide to write the app that manages the entire Azure Batch process as a .NET Core console application for now. First, the app uploads the pet videos to the cloud. It then creates an Azure Batch pool with compute nodes (Virtual Machines). The app then creates a job to run on those nodes.

Azure BatchThe job that runs on each compute node contains tasks for every video that has been uploaded to the input storage container. The task loads the MP4 pet videos, convert them to animated GIFs, and saves the files to an output container. The task reference the ffmpeg library that is stored as an application package in the Azure Batch account. Our solution is visualized in the following diagram.

Azure Batch is used in combination with Azure Storage. Azure Storage provides the location for any input data, a place for logging and monitoring information, and storage for the final output. The applications that an Azure Batch runs can also be stored there, or a more flexible option is to use the application package feature of Azure Batch.

The components of Azure Batch are:

Azure Batch account: A container that holds the following resources needed for our Azure Batch solution:

  • Application Package: Used to add applications that can be used by tasks in a Batch. An Azure Batch account can contain up to 20 application packages. A request can be made to increase this limit if your company requires more.
  • Pool: Contains compute nodes, which are the engines that run your Batch job. You specify the number, size, and operating system of nodes at creation time. An Azure Batch account can contain many pools.
  • Node: Each node can be assigned a number of tasks to run, the tasks are allocated and managed by Azure Batch. Nodes are associated with a specific pool.
  • Job: Jobs manage collections of tasks. A job is associated with a specific pool. An Azure Batch account can have many jobs.
  • Task: Tasks run applications. These can be contained in an application package, or in an Azure Storage container. Tasks process input files, and on completion can write to output containers.

Before you can start to manage the Azure Batch components from within a .NET application, you have to create the Azure Batch account and Azure Storage account. You can use Azure portal, Powershell, Hosting options or Azure CLI to create these accounts.

Why use an app to manage Batch workloads

Using an app to control Azure Batch processing enables you to automate the running and monitoring of the tasks in your Azure Batch. The rich set of client APIs that are available allow you to control the entire Batch workflow from your code. Once the batch processing has completed, the app can then delete the created resources automatically, keeping the Azure costs low.

Batch workloads make it possible to scale to thousands of nodes, making solutions that need processor intensive compute resources, like video trans-coding, weather forecasting, and image analysis more feasible. All these use cases become more efficient when they’re managed programmatically.

Batch client service APIs

Microsoft has released Batch APIs for a range of languages. Using these client libraries, you can programmatically control all the components of the Batch process. From the authentication, processing files, creating pools of nodes, creating jobs with tasks, and then monitoring the state of those running tasks.

In .NET, these Batch APIs are loaded as NuGet packages into your apps. We’ll also use the Azure Storage client library to manage files and assets in our solution.

How to use a .NET app to control Azure Batch

The steps you’ll be following in the rest of the module create Azure Batch and Azure Storage accounts using the Azure portal. Then you’ll upload the ffmpeg application as an application package to make it available to use in tasks. Your app will be using tasks that run ffmepg to convert the videos.

With the Batch and Storage accounts created in the Azure portal, you’ll then need to create a .NET Core console app in the Cloud Shell that uses the Azure Batch and Azure Storage client libraries.

Your app will use the Azure Storage client library to upload the MP4 videos into blob storage. The app will then use the Batch client library to create a pool with three nodes (Windows Server VMs), create a job, and then add video conversion tasks to the job to run on those nodes. With the tasks running, the app needs to monitor their status, check they complete successfully, and clear down unwanted resources.

Github search – Context & Using search filters

Context searches are available on certain tabs, such as Issues and Pull requests. These searches are scoped into the current repository and only return results of that type. The benefit to this scoping is that it allows the user interface to expose known type-specific filters, such as authors, labels, projects, and more.

Using the context search is the preferred website option when you’re looking for something in the current repository. In our scenario, this would be a good way to find search results mentioning “sidebar”, which could then be easily refined using the filter dropdowns.

Using search filters

There are an infinite number of ways to search using the complete search syntax . However, most searches only make use of a few common filters. While these are often available from context search dropdowns, it’s sometimes more convenient to type them in directly.

Here are some example filter queries:

Query Explanation
is:open is:issue assignee:@me Open issues assigned to the current user (@me)
is:closed is:pr author:contoso Closed pull requests created by @contoso
is:pr sidebar in:comments Pull requests where “sidebar” is mentioned in the comments
is:open is:issue label:bug -linked:pr Open issues labeled as bugs that do not have a linked pull request

Learn more about Understanding the search syntax