Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net core 在ASP.NET内核中存储生产机密_Asp.net Core - Fatal编程技术网

Asp.net core 在ASP.NET内核中存储生产机密

Asp.net core 在ASP.NET内核中存储生产机密,asp.net-core,Asp.net Core,我试图找出在哪里最好地存储ASP.NET核心应用程序的应用程序生产机密。有两个类似的问题 和 两者都建议使用环境变量 我的问题是,我想用不同的数据库和不同的数据库凭据运行我的web应用程序的多个实例。所以应该有一些每个实例的配置,包括秘密 如何以安全的方式实现这一点 请注意,应用程序应该能够自我托管,并且可以在IIS下托管!(稍后我们还计划在Linux上运行它,如果这对这个问题很重要的话) 更新 这个问题不是关于尝试在生产中使用ASP.NET用户机密!用户机密不适用于生产。正如它们所述,用户机密

我试图找出在哪里最好地存储ASP.NET核心应用程序的应用程序生产机密。有两个类似的问题 和 两者都建议使用环境变量

我的问题是,我想用不同的数据库和不同的数据库凭据运行我的web应用程序的多个实例。所以应该有一些每个实例的配置,包括秘密

如何以安全的方式实现这一点

请注意,应用程序应该能够自我托管,并且可以在IIS下托管!(稍后我们还计划在Linux上运行它,如果这对这个问题很重要的话)

更新


这个问题不是关于尝试在生产中使用ASP.NET用户机密!用户机密不适用于生产。

正如它们所述,用户机密仅用于开发(以避免将凭据意外提交给SCM),不适用于生产。每个数据库应使用一个连接字符串,即
连接字符串:CmsDatabaseProduction
连接字符串:CmsDatabaseDevelopment
,等等

或者使用docker容器(当您不使用Azure应用程序服务时),然后您可以根据每个容器进行设置

或者,也可以使用基于环境的appsetting文件
appsettings.production.json,但它们不能包含在源代码管理(Git、CSV、TFS)中

在启动过程中,只需执行以下操作:

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }

这样,您就可以从appsettings.production.json中加载特定的内容,并且仍然可以通过环境变量覆盖它

除了使用Azure应用程序服务或docker容器外,您还可以使用
IDataProtector
在生产中安全地存储应用程序机密:

  • 通过运行应用程序的-config开关输入应用程序机密,例如:
    dotnet helloworld-config
    ;在
    Program.Main
    中,检测此开关以允许用户输入机密并存储在单独的.json文件中,加密:
  • 公共类程序
    {
    专用常量字符串APP_NAME=“5E71EE95-49BD-40A9-81CD-B1DFD873EEA8”;
    private const string SECRET\u CONFIG\u FILE\u NAME=“appsettings.SECRET.json”;
    公共静态void Main(字符串[]args)
    {
    如果(args!=null&&args.Length==1&&args[0]。ToLowerInvariant()==“-config”)
    {
    ConfigAppSettingsCret();
    返回;
    }
    CreateWebHostBuilder(args.Build().Run();
    }
    公共静态IWebHostBuilder CreateWebHostBuilder(字符串[]args)=>
    WebHost.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((生成器,选项)=>
    {
    AddJsonFile(ConfigFileFullPath,可选:true,reloadOnChange:false);
    })
    .UseStartup();
    内部静态IDataProtector GetDataProtector()
    {
    var servicecolection=新servicecolection();
    serviceCollection.AddDataProtection()
    .SetApplicationName(应用程序ID)
    .PersistKeySystem(新目录信息(SecretsDirectory));
    var services=serviceCollection.BuildServiceProvider();
    var dataProtectionProvider=services.GetService();
    返回dataProtectionProvider.CreateProtector(应用程序ID);
    }
    私有静态无效ConfigAppSettingsCret()
    {
    var-protector=GetDataProtector();
    字符串dbPassword=protector.Protect(“dbPassword”,ReadPasswordFromConsole());
    ……其他秘密
    字符串json=…;//将加密的秘密序列化为json
    var path=ConfigFileFullPath;
    WriteAllText(路径,json);
    Console.WriteLine($“将应用程序设置机密写入${path}”已成功完成。”);
    }
    私有静态字符串目录
    {
    获取{return Directory.GetParent(typeof(Program).Assembly.Location.FullName;}
    }
    私有静态字符串ConfigFileFullPath
    {
    获取{return Path.Combine(CurrentDirectory,SECRET_CONFIG_FILE_NAME);}
    }
    }
    
  • 在Startup.cs中,读取并解密密码:
  • public void配置(IApplicationBuilder应用程序,IHostingEnvironment环境)
    {
    ...
    if(env.IsProduction())
    {
    var protector=Program.GetDataProtector();
    var builder=new-SqlConnectionStringBuilder();
    builder.Password=protector.Unprotect(配置[“DbPassword”]);
    ...
    }
    }
    

    顺便说一句,
    appsettings.production.json
    或环境变量实际上不是一个选项。顾名思义,机密永远不应该以纯文本形式存储。

    我知道在开发期间用户机密存在问题。但这不是问题所在,我只是在谈论生产时间!环境设置文件没有帮助,因为它对于生产中的每个实例仍然是相同的,并且覆盖环境变量对于所有实例仍然是相同的!我现在对Docker还不够了解,但也许这个想法会有所帮助。@NicolasR:不一定。每个安装将有一个application.production.json。如果您的应用程序位于3个不同的文件夹中,您可以将它们的
    applciation.production.json'设置为所需的值。您只需确保从源代码管理中排除
    application.production.json',因为它现在包含敏感数据。还有
    Microsoft.Extensions.Configuration.CommandLine,它可以从命令行参数读取配置,但是在ASP.NET内核中使用它并不容易,因为您在Startup类中构建了配置,并且您不容易从这里访问传递到
    Main的
    args
    参数method@NicolasR:嗯,据我所知,没有“安全字符串”就像传统ASP.NET应用程序中的一个,您可以将加密字符串放入web.config并在运行时对其进行解密,因此除非您编写