ASP.NET Core supports user secrets as part of its configuration system, which is the ability to store and retrieve configuration information on a per application and per user basis. This information is stored as key value pairs in a secrets.json file in the user profile directory. This is a perfect location for storing information that is user specific, like the username and password for social media and other services like twitter, facebook, github, etc. Since the user secrets are not stored in the .NET Core application directory, there is no chance the user secrets will be pushed to your source code repository and shared with others.

Don't be fooled by the term user secrets, however, the information stored in the secrets.json file is NOT encrypted by default. It is stored as plain text unless you encrypt it yourself. As I will show in a moment, here is a simple example of user secrets being stored in a secrets.json file as part of an ASP.NET Core MVC Web Application:

{
  "DataService.PublicKey": "abcd",
  "DataService.PrivateKey": "efgh"
}

ASP.NET Core MVC Web Application

User secrets do not require ASP.NET Core MVC, but I will write a quick ASP.NET Core MVC Web Application that uses user secrets as part of its configuration. I will be writing this web application on macOS using Visual Studio Code, but you can do this on a PC using Visual Studio if you wish. I open up a bash prompt on macOS and create a new ASP.NET Core MVC Web Application.

mkdir hush
cd hush

dotnet new
dotnet restore

code .

If you are not familiar with the code . command, it opens the current directory in Visual Studio Code.

I now add a few dependencies to project.json. Specifically, I need to add Microsoft.AspNetCore.Mvc for ASP.NET Core MVC and Microsoft.AspNetCore.Server.Kestrel for the Kestrel Web Server. Because I will be using the Razor View Engine, I also need to set a new build option: "preserveCompilationContext": true.

That is all I need to serve web pages with Kestrel and ASP.NET Core MVC, but I still need to add two more dependencies for user secrets: Microsoft.Extensions.Configuration.UserSecrets and Microsoft.Extensions.SecretManager.Tools.

Microsoft.Extensions.Configuration.UserSecrets allows me to use user secrets as part of the configuration system within my ASP.NET Core MVC Web Application, while Microsoft.Extensions.SecretManager.Tools is a command line Secret Manager tool to manage user secrets. I will show this in a moment, but for now here is the project.json file with all the dependencies for ASP.NET Core MVC and user secrets.

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },
  "userSecretsId": "hush-app",
  "dependencies": {
    "Microsoft.AspNetCore.Mvc": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
    "Microsoft.Extensions.Configuration.UserSecrets":"1.0.0"
  },
  "tools": {
    "Microsoft.Extensions.SecretManager.Tools":"1.0.0-preview2-final"
  },
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.0"
        }
      },
      "imports": "dnxcore50"
    }
  }
}

If you look closely, you will see the following setting in the project.json file.

"userSecretsId": "hush-app",

User secrets are stored on a per application basis for each user. Therefore, you must assign a unique userSecretsId to each application that uses user secrets. This is used to create a unique application directory in the user profile directory that will store the secrets.json file containing user secrets. I manually added the userSecretsId to the projects.json file.

Windows: %APPDATA%\microsoft\UserSecrets\<usersecretsid>\secrets.json
Linux: ~/.microsoft/usersecrets/<usersecretsid>/secrets.json
Mac: ~/.microsoft/usersecrets/<usersecretsid>/secrets.json

Now that a number of new dependencies have been added for ASP.NET Core MVC and user secrets, download and install the Nuget packages.

dotnet restore

Secret Manager Tool

The Secret Manager tool allows one to manage the secrets for the web application. You can get help for user secrets at the command prompt using dotnet user-secrets -h:

dotnet user-secrets -h

Usage: dotnet-user-secrets [options] [command]
Options:
  -?|-h|--help  Show help information
  -v|--verbose  Verbose output
Commands:
  clear   Deletes all the application secrets
  list    Lists all the application secrets
  remove  Removes the specified user secret
  set     Sets the user secret to the specified value

I set a couple of user secrets for my ASP.NET Core MVC Web Application using the dotnet user-secrets set command:

dotnet user-secrets set DataService.PublicKey abcd
info: Successfully saved DataService.PublicKey = abcd to the secret store.

dotnet user-secrets set DataService.PrivateKey efgh
info: Successfully saved DataService.PrivateKey = efgh to the secret store.

This results in the following secrets.json file mentioned at the beginning of the article.

{
  "DataService.PublicKey": "abcd",
  "DataService.PrivateKey": "efgh"
}

ASP.NET Core Configuration and User Secrets

The Microsoft.Extensions.Configuration.UserSecrets dependency added earlier adds an extension method that allows us to call AddUserSecrets when building the ASP.NET Core Configuration. The DataService.PublicKey and DataService.PrivateKey user secrets can then be read from the configuration and used to help configure the DataService. You can see all of this in the Startup Class.

using Hush.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Hush {
    public class Startup {
        public Startup(IHostingEnvironment env) {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath);

            builder.AddUserSecrets();

            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        public void ConfigureServices(IServiceCollection services) {
            services.AddMvc();

            var publicKey = Configuration["DataService.PublicKey"];
            var privateKey = Configuration["DataService.PrivateKey"];

            services.AddTransient<IDataService>(_ => new DataService(publicKey, privateKey));
        }

        public void Configure(IApplicationBuilder app) {
            app.UseMvcWithDefaultRoute();
        }
    }
}
namespace Hush.Services {
    public interface IDataService {
        string PublicKey { get; }
    }

    public class DataService : IDataService {
        private readonly string _publicKey;
        private readonly string _privateKey;

        public DataService(string publicKey, string privateKey) {
            _publicKey = publicKey;
            _privateKey = privateKey;
        }

        public string PublicKey { get { return _publicKey; } }
    }
}

ASP.NET Core Controller and View

Let's make sure this is working as expected. I will create an ASP.NET Core MVC Controller and View to display the public key stored in the secrets.json file.

using Microsoft.AspNetCore.Mvc;

namespace Hush.Controllers {
    public class HomeController : Controller {
        public IActionResult Index() {
            return View();
        }
    }
}
@using Hush.Services
@inject IDataService dataService
<!DOCTYPE html>
<html>
<head>
    <title>Hush Service</title>
</head>
<body>
    <h1>Hush</h1>
    <p>Public Key: @dataService.PublicKey</p>
</body>
</html>

ASP.NET Core View Injection

For kicks, I did something with the view that I have not showed before so I want to emphasize it with its own section. Instead of injecting the dataService into the controller, I inject dataService into the view using @inject.

@inject IDataService dataService

Once the service is injected into the view I can display the user secret on the Razor View Page.

<p>Public Key: @dataService.PublicKey</p>

Run ASP.NET Core MVC Web Application to Display User Secrets

Let's run the ASP.NET Core MVC Web Application to display the user secrets stored as part of the ASP.NET Core Configuration.

dotnet run

Project hush (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
Hosting environment: Production
Content root path: /Users/Sasquatch/Core/hush
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

ASP.NET Core MVC and User Secrets

Conclusion

I hope you enjoyed the article. There is a lot more to configuring ASP.NET Core MVC Web Applications that I will talk about in future articles.

You can find me on twitter as @KoderDojo. Best Wishes!

Posted by Koder Dojo

Hi, and welcome to Koder Dojo. I am a freelance C#, ASP.NET MVC Developer learning Python and ASP.NET Core during my free time. I journal my experience on this website to help me retain and share my knowledge with others. I regularly write articles and mention them on twitter as @KoderDojo. Best Wishes!

Related Posts: