How To Manage User Secrets In ASP.NET Core
When working with ASP.NET web applications, you will want to protect certain pieces of application data, called user secrets, that should not be shared with others. Your user secrets might include a database connection string that also contains the user ID and the password for the database. You might also want to refrain from sharing information such as access keys, API keys, and connection information details for cloud services such as Azure or AWS.
How to manage user secrets in ASP.NET Core
However, when you share your project with others this secret information also will be shared. How can we prevent this? A feature in ASP.NET Core named User Secrets allows you to store user secrets outside your project tree in a JSON file, and can even be managed using a command-line tool called the Secrets Manager. This article talks about how you can work with the User Secrets API in ASP.NET Core.
Adding user secrets management to your project is fairly straightforward. All you need to do is select the project in the Solution Explorer window, right-click on the project, and then select Manage User Secrets as shown in Figure 1 below.
However, one downside is that the data that is stored by User Secrets is not encrypted. I will discuss other options for protecting user secrets such as Azure application settings and Azure key vault in a future article here.
This document explains how to manage sensitive data for an ASP.NET Core app on a development machine. Never store passwords or other sensitive data in source code. Production secrets shouldn't be used for development or test. Secrets shouldn't be deployed with the app. Instead, production secrets should be accessed through a controlled means like environment variables or Azure Key Vault. You can store and protect Azure test and production secrets with the Azure Key Vault configuration provider.
Environment variables are generally stored in plain, unencrypted text. If the machine or process is compromised, environment variables can be accessed by untrusted parties. Additional measures to prevent disclosure of user secrets may be required.
The Secret Manager tool doesn't encrypt the stored secrets and shouldn't be treated as a trusted store. It's for development purposes only. The keys and values are stored in a JSON configuration file in the user profile directory.
The JSON structure is flattened after modifications via dotnet user-secrets remove or dotnet user-secrets set. For example, running dotnet user-secrets remove "Movies:ConnectionString" collapses the Movies object literal. The modified file resembles the following JSON:
The user secrets configuration source is automatically added in Development mode when the project calls CreateDefaultBuilder. CreateDefaultBuilder calls AddUserSecrets when the EnvironmentName is Development:
When CreateDefaultBuilder isn't called, add the user secrets configuration source explicitly by calling AddUserSecrets in ConfigureAppConfiguration. Call AddUserSecrets only when the app runs in the Development environment, as shown in the following example:
If the user secrets configuration source is registered, the .NET Configuration API can read the secrets. Constructor injection can be used to gain access to the .NET Configuration API. Consider the following examples of reading the Movies:ServiceApiKey key:
There are two ways we can manage user secrets in our application. The first one is the manual approach, and the second one uses the command dotnet user-secrets, and we'll focus more on using this command.
Note: If you don't want to interact with the command line, you can just right-click on your project and select "Manage User Secrets" to initialize the user secrets for you. You can manually input the configuration settings inside VS.
Please notice that I added this piece of code to only be running if the environment is running in development mode. You should only be using user secrets when developing and not when running in production mode.
I hope this short guide about user secrets has given you a more easy way to handle individual developer settings in a more secret way for your team. If you got any issues, questions, or suggestions, please let me know in the comments. Happy coding! ?
Unlike environment variables, user secrets are placed in a settings file similar to appsettings.json. Having similar structured off-project settings is great when you need to copy keys and values between files and there is support for adding, removing, and listing values as I will show you later in this post.
This creates and opens a new empty JSON file named secrets.json. The file is placed beneath C:\Users\\AppData\Roaming\Microsoft\UserSecrets\ where matches your Windows user and is a randomly generated GUID. The important thing to notice here is that the file is located outside your project directory. In order to "bind" the secrets.json file location to your project, Visual Studio added a bit of markup to the csproj file:
Notice how I only add user secrets when running in development mode. User secrets is a feature meant for developing only and should be replaced with something else when hosting on Azure, IIS, or another production environment.
Remember environment variables from the last post? The nice thing about user secrets is that they can be used together with environment variables if you like. Settings override in the order they are added to the configuration. If you are using WebHost.CreateDefaultBuilder, environment variables override user secrets which again override settings in appsettings.json. If you want to change the order of override, you will need to configure your app manually and append the config providers in a different order:
To make this even more relevant to elmah.io users, let's utilize user secrets to configure individual elmah.io logs per developer machine. For the example, I'm using the Elmah.Io.AspNetCore package, but this could be anything in the need of configuration really.
To summarize, user secrets are a great alternative to environment variables. The structure matches that of appsettings.json files and there is great tool support for administrating secrets. Popular IDEs like Visual Studio and Code already support the format and there are tools like this JSON formatter and validator to help you write valid JSON. Unlike what the name implies, user secrets are not really a secret. Settings are still stored on the disk in cleartext. People would still need to have access to your Windows account, though. Under all circumstances, user secrets are a great feature in ASP.NET Core and make individual settings easily accessible.
A common way to deal with sensitive data in an app is by using Environment Variables. With the arrival of .NET Core we now have a tidy way of managing configuration and sensitive data in the form of User Secrets, which can be managed by the Secrets Manager Tool (SMT) from the command line. User Secrets are stored outside of the project tree in a JSON configuration file in the user profile directory and are therefore outside of source control.
When you're developing websites and web API's using ASP.NET Core, you often have passwords, API keys, and other secrets you wish to keep away from prying eyes. Adding these secrets to a configuration file, like appsettings.json, and accidentally pushing these to a Git repository could be disastrous. For development purposes, Microsoft provides a secret manager tool that stores sensitive data in a separate secrets.json file on your development PC that is read by the default configuration builder in ASP.NET Core. As such, you can avoid placing these secrets in your configuration files and accidentally adding them to your Git repository.
Secrets stored by the secret manager tool can be managed directly in Visual Studio by right-clicking the Visual Studio project file or at the command line. From the command line you need to be in the same directory as your project file and initialize the project to use secrets.
Using secrets in an ASP.NET Core Razor Pages website or ASP.NET Core Web API is no different than reading configuration information into your project. As mentioned earlier, when you read configuration data into your web application it is read in a particular order from a variety of sources, one of those default sources being user secrets.
Let's say I have an ASP.NET Core Razor Pages website and I wish to read the API key into my application from configuration. I configure the appsettings.json file to hold a dummy value for this API key for illustration purposes and have stored the real development API key in secrets.json using the secret manager tool. The appsettings.json file contains the following information.
The variable apiKey should be 12345 if you've successfully added the secret using the secret manager tool as mentioned above. If you haven't added the secret, the value will be dummy. Again, this is because the ApiKey setting in secrets will overwrite the ApiKey setting in appsettings.json, thereby allowing you to commit this code into a Git repository with dummy data and having the real developer API key replace the dummy value when you run it locally during application development. 041b061a72