Home > other >  where to store database credentials in an ASP.NET core web api project
where to store database credentials in an ASP.NET core web api project

Time:07-22

this is my first project in asp.net core and i don't seem to figure out where to store a postgres db credentials. i've read that they need to be stored in appsettings.json but if i do so, do i need to add it to the .gitignore file and do i have the ability to add it when pushing to production or should i use a .env file.

PS: i still don't know where the project will be hosted so do all hosts support appsettings.json configurations ?

CodePudding user response:

Answer to second question - appsettings.json is just a file, part of dotnet publish output and it should work on any host that supports uploading files.

This is somewhat pet issue of mine, so answer to first question will be longer. You definitely don't want your passwords to go to git, you are right on that. If you want to stay with official solution, you are supposed to use application secrets for local development, and appsettings.{Develoment,Staging,Production}.json on servers where you deploy the application. They stack, what is in appsettings.json will be overriden by anything you put in one of the .env files with same key. I myself do have several issues with this approach.

  • appsecrets only work in development environment (unless you rewrite your default Startup class). If you are doing both development and maintenance, you have to mentally switch between two approaches to one thing.
  • appsecrets have their own special utility which you have to learn, while appsettings.* family are files in a well known path inside a project that you can edit with anything (secrets are a file too, with the same syntax, but it lives somewhere deep in %APPDATA%, out of normal reach. You have to search for it).
  • appsettings.{env}.json - should they be in git or not? No offical answer on that that I know of. Most projects I dealt with had some kind of a problem with these two files. If it lives in git, you have the same problem as appsettings.json - you can't put sensitive info into them. And you have to exclude if from publishing, because your git version won't have correct passwords. I have seen a few horrible teamcity scripts trying ensure this during build/publish step, and then randomly fail when devs change things that should have no impact on this (like target dotnet version). If they are not in git and you DO need to update server version? You have to make sure to merge the changes to live version manually. Which is easy to forget.

Neither of those points is a dealbreaker, but they leave bad taste for me.

After some meditation on those issues, I introduced appsettings.local.json file as standard part of any of our projects. It's in .gitignore, it never leaves the machine.

return Host.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((hostBuilderContext, configurationBuilder) =>
    {
        ContentRootPath = hostBuilderContext.HostingEnvironment.ContentRootPath;
        for (int pos = configurationBuilder.Sources.Count - 1; pos >= 0; --pos)
        {
            if (configurationBuilder.Sources[pos] is JsonConfigurationSource)
            {
                var source = new JsonConfigurationSource()
                {
                    Path = Path.Join(ContentRootPath, "appsettings.local.json"),
                    Optional = true,
                    ReloadOnChange = true,
                };
                source.ResolveFileProvider();
                configurationBuilder.Sources.Insert(pos   1, source);
            }
        }
    })

This belongs in Program.cs (old style, it needs slight modification if you use toplevel statements) and places it into the chain of "stock" configuration providers, just after all other configuration files. They continue to work as before, but if .local file is present, values from it override other .json files.

With this, appsettings.json serves just as a template, it's tracked by git and if you have some discipline, it also serves as a structured overview of everything that can be configured, with default values. If the project has different needs for staging/prod environments, corresponding .env files still work, and can be tracked by git. Passwords go to .local file, everywhere.

  • Related