从JSON和环境变量中读取配置部分会得到不同的结果

时间:2018-01-25 17:19:23

标签: asp.net-core configuration .net-core environment-variables

我正在尝试了解.NET Core 2中的配置源。我有一些秘密配置,在我的开发环境中存储在项目secrets.json中。因为我不希望这些秘密存在于存储库中,所以在生产中我想从环境变量中加载这些秘密。我的理解是ConfigurationBuilder允许我交替使用配置源,但它们的加载方式不同。

我的secrets.json文件看起来有点像这样:

{
  "MyApi" : {
    "APIKEY": "12341234123412341234",
    "TemplateIds": {
      "MyTemplate": "abcdabcdabcdabcdabcdabcd"
    }
  }
}

这将按照预期加载builder.GetSection("MyApi").AsEnumerable()作为包含以下项目的列表:

{[MyApi, ]}
{[MyApi:APIKEY, "12341234123412341234"]}
{[MyApi:TemplateIds, ]}
{[MyApi:TemplateIds:MyTemplate, "abcdabcdabcdabcdabcdabcd"]}

但是当我设置一个名为MyApi的环境变量,其值为{"APIKEY": "12341234123412341234", "TemplateIds": {"MyTemplate": "abcdabcdabcdabcdabcdabcd"}时,用builder.GetSection("MyApi").AsEnumerable()加载它只会产生一个值,设置为整个JSON字符串。

我的配置构建器如下所示:

var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("secrets/appsettings.secrets.json", optional: true)
    .AddEnvironmentVariables();

那么,这两种加载配置的方法是否应该给出相同的结果,如果有的话,是否有人知道为什么它们在这种情况下会有所不同?

1 个答案:

答案 0 :(得分:4)

那是因为环境变量提供程序不处理JSON 。如果要通过环境变量指定这些设置,则需要将每个设置为自己的环境变量。例如,对于APIKEY,您需要一个名为MyApi.APIKEY的环境变量,其值为12341234123412341234。冲洗并重复其余设置。您需要通过使用.:加入每个级别来表示JSON中存在的层次结构。

那就是说,你应该使用用户机密,而不是像secrets.json那样创建。它的工作方式大致相同,而且它也是JSON,但它使它完全从项目中抽象出来,所以没有文件你必须忽略,也没有最终可能最终提交的文件。

此外,对于它的价值,所有设置应该在appsettings.json或其中一个特定于环境的版本中。对于“秘密”,只需放置占位符或空值即可。然后可以通过更具体的配置(例如用户机密,环境变量,Azure KeyVault等)覆盖它。这样,您的应用程序所需的所有配置都记录在 检查到源代码管理中的内容中,但是实际的秘密值不是。否则,对于可能需要使用该应用程序的其他开发人员来说,了解他们需要提供哪些设置可能非常困难。例如:

{
  "MyApi" : {
    "APIKEY": "***SET IN USER SECRETS OR ENVIRONMENT VARIABLE***",
    "TemplateIds": {
      "MyTemplate": "abcdabcdabcdabcdabcdabcd"
    }
  }
}