DEV Community

Bradley Wells
Bradley Wells

Posted on • Originally published at wellsb.com on

How to avoid storing secrets in ASP.NET source code

Original Article

It’s never a good idea to store secrets or password in your project’s source code. In an ASP.NET Core development environment, you can use the Secret Manager tool to store sensitive data.

Introduction to Secret Manager

The Secret Manager tool stores your application secrets in a secrets.json file located in your development machine’s %appdata%\Microsoft\UserSecrets\<UserSecretsId>\ directory.

Secret Manager is only intended to be used in a development environment. It does not encrypt the stored keys and values. Once your app is in production, you can, of course, use a service like the Azure Key Vault.

Using Secret Manager

You can access secrets stored using Secret Manager the same way you would pull data from your appsettings.json file. However, because the secrets are not stored in your project’s directory, you run less risk of accidentally checking your passwords in to a source control repository.

To enable the Secret Manager utility, open your project in Visual Studio. Then, locate your project in the Solution Explorer. Right click the project and select Manager User Secrets. This will automatically generate a UserSecretsId in your project’s .csproj configuration file, and it will open the associated secrets.json file.

Suppose you must include a Client ID and Secret in order to access a private API. Rather than including them directly in your C# source code, you could add them to secrets.json as follows:

{
  "ClientId": "myclientid",
  "ClientSecret": "00aaaa0a-00aa-00aa-00aa-00aaaa0000aa"
}

Access Secrets in Startup

To access the data stored in the Secret Manager, simply use the Configuration API available in .NET Core. Keys are often needed as part of a project’s Startup routine, so open your project’s Startup.cs.

If you are not already using it, go ahead an inject an instance of the Configuration provider interface into the Startup constructor.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    ...

}

Now, you can use the instance in either the ConfigureServices() method or the Configure()method of Startup.cs using the following syntax.

var value = Configuration["key"];

For example, to access the values for the two keys in the Secret Manager, ClientId and ClientSecret, you might do something similar to the following.

string Id = Configuration["ClientId"]; //myclientid
string Secret = Configuration["ClientSecret"]; //00aaaa0a-00aa-00aa-00aa-00aaaa0000aa

The Id variable will now hold the value associated with the ClientId key from secrets.json. In other words, Id is a string variable with value myclientid. The string variable Secret has a value of 00aaaa0a-00aa-00aa-00aa-00aaaa0000aa.

Access Secrets in Blazor, Razor Pages

To use the data stored in Secret Manager in a Razor page, simply inject an instance of IConfiguration into the page.

@inject IConfiguration Configuration

Now, you can access your secrets by using Razor syntax and the Configuration API. For example, the following would display the ClientSecret.

<p>Your secret is @Configuration["ClientSecret"]</p>

The Bottom Line

In this tutorial, you learned a useful technique for keeping sensitive data out of your ASP.NET Core project’s source code using Secret Manager in a development environment. This is good practice to help ensure you do not accidentally commit passwords or secrets to source control, which could put your application or users at risk.

Source

Latest comments (1)

Collapse
 
atipparaju profile image
Atipparaju

Bradley, thanks for the article.
Is there any way we can use the user secrets created/stored in a common library across multiple projects in the same solution?
Here is the scenario:
Solution A has Projects AA, AB, AC and a Common Library (CL) project. AA, AB, AC are API projects. I have User Secrets in CL project which I want to access in AA, AB, AC at run time.