当我创建 核心 Web 应用程序时,我会在测试期间使用密钥管理器.我通常能够创建一个新的 web 项目(mvc 和 web api),右键单击该项目并选择管理用户机密".这将打开一个 json 文件,我在其中添加秘密.然后我在我的 startup.cs 中使用它,如下所示:
When I create core web applications, I use the secret manager during testing. I am generally able to create a new web project (mvc and web api), right click on the project and select "manage user secrets". This opens a json file where I add the secrets. I then use this in my startup.cs something like this:
services.AddDbContext<ApplicationDbContext>(options => options.UseMySql(Configuration["connectionString"]));该网站可以正常工作,并且可以很好地连接到数据库.但是,当我尝试使用 add-migration 等 ef 核心迁移命令时,它们似乎无法从密钥管理器访问连接字符串.我收到错误消息连接字符串不能为空".当我使用实际字符串对 Configuration["connectionString"] 进行硬编码时,错误消失了.我在网上查了一下.csproj文件,它们已经包含以下几行:
The website works fine with this and connects well to the database. However when I try using ef core migration commands such as add-migration, they don't seem to be able to access the connection string from the secret manager. I get the error saying "connection string can't be null". The error is gone when I hard code Configuration["connectionString"] with the actual string. I have checked online and checked the .csproj file, they already contain the following lines:
<UserSecretsId>My app name</UserSecretsId>后来:
<ItemGroup> <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.1" /> <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" />我需要添加什么以便迁移可以访问连接字符串吗?
Is there anything I need to add so the migrations can access the connection string?
更新
我在上下文类中只有一个构造函数:
I only have one constructor in the context class:
public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options) : base(options) { } 推荐答案我目前也遇到了这个确切的问题.我想出了一个目前可行的解决方案,但充其量可能会认为是混乱的.
I am currently coming across this exact problem as well. I have come up with a solution that works for now, but one may consider messy at best.
我创建了一个配置类,它在请求时提供配置接口:
I have created a Configuration Class that provides the Configuration Interface when requested:
public static class Configuration { public static IConfiguration GetConfiguration() { return new ConfigurationBuilder() .AddJsonFile("appsettings.json", true, true) .AddUserSecrets<Startup>() .AddEnvironmentVariables() .Build(); } }在迁移中,您可以像这样获取配置文件并访问其 UserSecrets:
In the Migration, you can then get the Configuration File and access its UserSecrets like this:
protected override void Up(MigrationBuilder migrationBuilder) { var conf = Configuration.GetConfiguration(); var secret = conf["Secret"]; }我已经测试过使用这些用户密码创建一个 SQL 脚本,并且它可以工作(你显然不想让脚本到处乱放,因为它会暴露实际的密码).
I have tested creating a SQL Script with these User Secrets, and it works (you obviously wouldn't want to keep the Script laying around since it would expose the actual secret).
更新
上述配置也可以在BuildWebHost方法中设置到Program.cs类中:
The above config can also be set up into Program.cs class in the BuildWebHost method:
var config = new ConfigurationBuilder().AddUserSecrets<Startup>().Build(); return WebHost.CreateDefaultBuilder(args).UseConfiguration(config)...Build()如果使用 ,则在启动构造函数中该公约
更新 2(说明)
事实证明,这个问题是因为迁移脚本在环境设置为生产"的情况下运行.秘密管理器预设为仅在开发"中工作.环境(有充分的理由)..AddUserSecrets<Startup>() 函数只是添加所有环境的秘密.
It turns out this issue is because the migration scripts runs with the environment set to "Production". The secret manager is pre-set to only work in "Development" environment (for a good reason). The .AddUserSecrets<Startup>() function simply adds the secrets for all environment.
为确保未将其设置为您的生产服务器,我注意到有两种解决方案,此处建议使用一种:docs.microsoft/en-us/ef/core/miscellaneous/cli/powershell
To ensure that this isn't set to your production server, there are two solutions I have noticed, one is suggested here: docs.microsoft/en-us/ef/core/miscellaneous/cli/powershell
在运行前设置 env:ASPNETCORE_ENVIRONMENT 以指定 ASP.NET Core 环境.
Set env:ASPNETCORE_ENVIRONMENT before running to specify the ASP.NET Core environment.
此解决方案意味着将来无需在计算机上创建的每个项目上设置 .AddUserSecrets<Startup>().但是,如果您碰巧在其他计算机上共享此项目,则需要在每台计算机上进行配置.
This solution would mean there is no need to set .AddUserSecrets<Startup>() on every project created on the computer in future. However if you happen to be sharing this project across other computers, this needs to be configured on each computer.
第二个解决方案是设置 .AddUserSecrets<Startup>() 仅在调试构建时像这样:
The second solution is to set the .AddUserSecrets<Startup>() only on debug build like this:
return new ConfigurationBuilder() .AddJsonFile("appsettings.json", true, true) #if DEBUG .AddUserSecrets<Startup>() #endif .AddEnvironmentVariables() .Build();其他信息
配置接口可以在其构造函数中传递给控制器,即
The Configuration Interface can be passed to Controllers in their Constructor, i.e.
private readonly IConfiguration _configuration; public TestController(IConfiguration configuration) { _configuration = configuration; }因此,可以通过访问 _configuration[secret"] 在该控制器中访问任何 Secrets 和 Application Setting.
Thus, any Secrets and Application Setting are accessible in that Controller by accessing _configuration["secret"].
但是,如果您想从例如 Web 应用程序本身之外存在的迁移文件访问应用程序机密,则需要遵守原始答案,因为没有简单的方法(据我所知)否则访问这些秘密(我能想到的一个用例是使用管理员和主密码为数据库播种).
However, if you want to access Application Secrets from, for example, a Migration-File, which exists outside of the Web Application itself, you need to adhere to the original answer because there's no easy way (that I know of) to access those secrets otherwise (one use case I can think of would be seeding the Database with an Admin and a Master Password).
更多推荐
ef核心迁移不能使用秘密管理器
发布评论