英文:
.NET Core 6 : to protect potentially sensitive information in your connection string
问题
如何将敏感信息移至“秘密管理工具”中?
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer("Server=Test; column encryption setting=enabled;Database=Test;user id=User1;password='Password1';Trust Server Certificate=true");
我知道我可以右键单击解决方案名称,然后选择“管理用户秘密”,然后生成秘密的 JSON 文件,但我应该粘贴什么到这个文件中呢?
当我将这个应用程序移到生产服务器时,我需要复制并粘贴secret.json
吗?
提前感谢。
英文:
How do I move sensitive information below into the 'The Secret Manager Tool'?
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer("Server=Test; column encryption setting=enabled;Database=Test;user id=User1;password='Password1';Trust Server Certificate=true");
I know I can right click on the solution name and select "Manage User Secrets", which then generates the secret Json file, but what I am pasting into this file?
And when I move this application over to the production server, do I copy & paste over the secret.json
as well?
Thanks in advance.
答案1
得分: 5
以下是翻译好的部分:
"你需要稍微退一步,考虑 ASP.NET Core/.NET 提供的配置工具。"
"从DbContext 生命周期、配置和初始化文档中,你可以看到一个常见模式是使用依赖注入,在应用程序启动时设置连接字符串。这将需要向上下文添加构造函数(并修改/删除OnConfiguring
重载 - 文档):"
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
以及:
builder.Services.AddDbContext<ApplicationDbContext>(
options => options.UseSqlServer("ConnectionStringHere")); // 或 AddDbContextFactory
下一步是从设置中读取连接字符串:
builder.Services.AddDbContext<ApplicationDbContext>(
options => options.UseSqlServer(builder.Configuration.GetConnectionString("ConnStringName"))); // 或 AddDbContextFactory
这将需要从配置中读取连接字符串,例如从 appsettting.json:
{
"ConnectionStrings": {
"ConnStringName": "ACTUAL_CONNECTION_STRING"
},
}
此外,你还可以将连接字符串移到任何受支持的配置提供程序中,例如 - Secret Manager(注意,它仅适用于开发环境,对于其他环境最好使用环境变量或安全的密钥存储)。
英文:
You need to take a small step back and consider tools ASP.NET Core/.NET provides to work with configuration.
From DbContext Lifetime, Configuration, and Initialization doc you can see that one of the common pattern is to use dependency injection and setup the the connection string on application startup. This will require adding constructor to the context (and modifying/removing OnConfiguring
overload - docs):
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
And:
builder.Services.AddDbContext<ApplicationDbContext>(
options => options.UseSqlServer("ConnectionStringHere")); // or AddDbContextFactory
Next step is to read the connection string from the settings:
builder.Services.AddDbContext<ApplicationDbContext>(
options => options.UseSqlServer(builder.Configuration.GetConnectionString("ConnStringName"))); // or AddDbContextFactory
Which will require connection string to be read from the configuration, for example from appsettting.json:
{
"ConnectionStrings": {
"ConnStringName": "ACTUAL_CONNECTION_STRING"
},
}
Also you can move connection string to any of the supported configuration providers, for example - Secret Manager (note, it is for development environment only, for other environments is better to use either environment variables or secured key storages).
答案2
得分: 1
在运行AWS、GCP或Azure中的生产应用程序时,我们将所有机密信息保存在云提供商的相应秘密管理器中(例如AWS Secrets Manager),并在创建运行时环境时使用脚本将这些机密信息注入环境变量中。
请注意,所谓的“Secrets Manager”,我指的不是.NET的Secret Manager,它仅在开发机器上将机密信息存储在文件中。
.NET可以从环境中读取配置,包括连接字符串。
采用这种方法,只有受信任的DevOps人员才能查看连接字符串。它永远不会出现在文件中,当然绝对不会出现在源代码控制中。
英文:
When running production apps in AWS, GCP, or Azure, we keep all secrets in the cloud provider's respective secret manager (e.g. AWS Secrets Manager) and use scripting when the runtime environment is created to inject those secrets into environment variables.
Note, by Secrets Manager, I don't mean the .NET Secret Manager, which merely stores secrets in a file on the development machine.
.NET can read configuration from the environment, including connection strings.
With this approach, only trusted DevOps personnel ever have the ability to view a connection string. It is never in a file, and certainly never in source control.
答案3
得分: 0
在生产服务器上,您需要创建一个与生产连接字符串同名的配置键。
将ASPNETCORE_ENVIRONMENT变量设置为"Production"。
当环境变量"ASPNETCORE_ENVIRONMENT"为"Production"时,将忽略secrets.json源。您可以在默认应用程序配置来源中查看此信息。
根据ASP.NET Core文档,
WebApplication.CreateBuilder使用预配置的默认值初始化WebApplicationBuilder类的新实例。初始化的WebApplicationBuilder(builder)以从高到低的优先级为应用程序提供默认配置:
- 使用命令行配置提供程序的命令行参数。
- 使用非前缀环境变量配置提供程序的非前缀环境变量。
- 当应用程序在开发环境中运行时,使用用户机密。
- 使用JSON配置提供程序的appsettings.{Environment}.json。例如,appsettings.Production.json和appsettings.Development.json。
- 使用JSON配置提供程序的appsettings.json。
- 使用下一节中描述的主机配置作为后备。
英文:
In the production server you need to create a configuration key with the same name with the production connection string.
Set the ASPNETCORE_ENVIRONMENT variable to "Production"
When environment "ASPNETCORE_ENVIRONMENT" is in "Production" the secrets.json source is ignored. You can check this in Default application configuration sources
According to ASP.NET Core documentation
WebApplication.CreateBuilder initializes a new instance of the WebApplicationBuilder class with preconfigured defaults. The initialized WebApplicationBuilder (builder) provides default configuration for the app in the following order, from highest to lowest priority:
- Command-line arguments using the Command-line configuration provider.
- Non-prefixed environment variables using the Non-prefixed environment variables configuration provider.
- User secrets when the app runs in the Development environment.
- appsettings.{Environment}.json using the JSON configuration provider. For example, appsettings.Production.json and appsettings.Development.json.
- appsettings.json using the JSON configuration provider.
- A fallback to the host configuration described in the next section.
答案4
得分: 0
在生产服务器上配置连接字符串的最佳方法是配置Windows身份验证。
- 必须配置一个网络用户。应该在SQL Server中为该用户授予权限。
- 配置Web服务器池时,将此池运行在第1步创建的身份下。
- 此时,您的连接字符串将如下所示:
Server=MyServerName;Database=MyDbName;Trusted_Connection=SSPI;Encrypt=false;TrustServerCertificate=true
。如您所见,没有password
或user
。
通过这种设置,除非攻击者知道池运行的帐户密码,这是相当安全的。
如果坚持使用SQL身份验证,您需要将凭据存储在安全的凭据管理器中(即使是自制的),然后在运行时获取它们并构建连接字符串。
英文:
Best that you can do for the connection string in the production server is to configure windows authentication.
- There must be a network user configured. This user should be given permissions in the SQL Server.
- When you configure your Web server pool, run this pool under identity created in #1
- At this point your connection string will look like this
Server=MyServerName;Database=MyDbName;Trusted_Connection=SSPI;Encrypt=false;TrustServerCertificate=true
. As you see - nopassword
oruser
With this setup, unless attacker knows password to the account under which your pool runs, this is plenty secure.
If you insist in using Sql Authentication, you need to store your credentials in the secure secrets manager (even if homegrown) and then acquire them and build connection string at runtime.
答案5
得分: 0
最简单的解决方案可以是:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer("Name=ConnectionStrings:DB1ConnectionString");
以及你的 appsetting.json
:
{
"ConnectionStrings": {
"DB1ConnectionString": "Data Source=sqlServer;Initial Catalog=<databseName>;User=<UserName>;Password=<Password>;TrustServerCertificate=True",
"DB2ConnectionString": ...
}
}
英文:
The simplest solution can be
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer("Name=ConnectionStrings:DB1ConnectionString");
and your appsetting.json
{
"ConnectionStrings": {
"DB1ConnectionString": "Data Source=sqlServer;Initial Catalog=<databseName>;User=<UserName>;Password=<Password>;TrustServerCertificate=True"
"DB2ConnectionString": ...
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论