我正在尝试了解.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();
那么,这两种加载配置的方法是否应该给出相同的结果,如果有的话,是否有人知道为什么它们在这种情况下会有所不同?
答案 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"
}
}
}