Nev*_*ane 11 secret-manager visual-studio-2017 asp.net-core-2.0 entity-framework-core-migrations
当我创建 .net core web 应用程序时,我在测试期间使用了秘密管理器。我通常能够创建一个新的 web 项目(mvc 和 web api),右键单击该项目并选择“管理用户机密”。这将打开一个 json 文件,我在其中添加了机密。然后我在我的 startup.cs 中使用它,如下所示:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(Configuration["connectionString"]));
Run Code Online (Sandbox Code Playgroud)
该网站在此方面运行良好,并且可以很好地连接到数据库。但是,当我尝试使用诸如 ef 核心迁移命令时add-migration,它们似乎无法从秘密管理器访问连接字符串。我收到错误消息“连接字符串不能为空”。当我Configuration["connectionString"]用实际字符串硬编码时,错误消失了。我已经在线检查并检查了 .csproj 文件,它们已经包含以下几行:
<UserSecretsId>My app name</UserSecretsId>
Run Code Online (Sandbox Code Playgroud)
然后:
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.1" />
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" />
Run Code Online (Sandbox Code Playgroud)
是否需要添加任何内容以便迁移可以访问连接字符串?
更新
我在上下文类中只有一个构造函数:
public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options) : base(options)
{
}
Run Code Online (Sandbox Code Playgroud)
小智 8
我目前也遇到了这个确切的问题。我已经提出了一种目前有效的解决方案,但充其量可能会被认为是混乱的。
我创建了一个配置类,在请求时提供配置接口:
public static class Configuration
{
public static IConfiguration GetConfiguration()
{
return new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
.AddUserSecrets<Startup>()
.AddEnvironmentVariables()
.Build();
}
}
Run Code Online (Sandbox Code Playgroud)
在迁移中,您可以获取配置文件并像这样访问它的 UserSecrets:
protected override void Up(MigrationBuilder migrationBuilder)
{
var conf = Configuration.GetConfiguration();
var secret = conf["Secret"];
}
Run Code Online (Sandbox Code Playgroud)
我已经测试过使用这些用户机密创建 SQL 脚本,并且它可以工作(您显然不想保留脚本,因为它会暴露实际的机密)。
更新
上面的配置也可以在BuildWebHost方法中设置到Program.cs类中:
var config = new ConfigurationBuilder().AddUserSecrets<Startup>().Build();
return WebHost.CreateDefaultBuilder(args).UseConfiguration(config)...Build()
Run Code Online (Sandbox Code Playgroud)
或者如果使用该约定,则在启动构造函数中
更新 2(说明)
事实证明,这个问题是因为迁移脚本在环境设置为“生产”的情况下运行。秘密管理器预设为仅在“开发”环境中工作(有充分的理由)。该.AddUserSecrets<Startup>()函数只是为所有环境添加秘密。
为确保未将其设置为您的生产服务器,我注意到有两种解决方案,此处建议使用一种:https : //docs.microsoft.com/en-us/ef/core/miscellaneous/cli/powershell
在运行之前设置 env:ASPNETCORE_ENVIRONMENT 以指定 ASP.NET Core 环境。
此解决方案意味着.AddUserSecrets<Startup>()将来无需在计算机上创建的每个项目上进行设置。但是,如果您碰巧在其他计算机上共享此项目,则需要在每台计算机上进行配置。
第二种解决方案是设置.AddUserSecrets<Startup>()only on debug build ,如下所示:
return new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
#if DEBUG
.AddUserSecrets<Startup>()
#endif
.AddEnvironmentVariables()
.Build();
Run Code Online (Sandbox Code Playgroud)
附加信息
配置接口可以在它们的构造函数中传递给控制器,即
private readonly IConfiguration _configuration;
public TestController(IConfiguration configuration)
{
_configuration = configuration;
}
Run Code Online (Sandbox Code Playgroud)
因此,通过访问_configuration["secret"].
但是,如果您想从,例如,存在于 Web 应用程序本身之外的迁移文件访问应用程序机密,则需要遵循原始答案,因为没有简单的方法(据我所知)来访问那些否则秘密(我能想到的一个用例是使用管理员和主密码为数据库播种)。
要在 NetCore 中使用具有用户机密的迁移,我们还可以设置一个类 (SqlContextFactory) 以使用指定的配置生成器创建自己的 SqlContext 实例。这样我们就不必在程序或启动类中创建某种解决方法。下面的示例SqlContext是DbContext/IdentityDbContext.
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
public class SqlContextFactory : IDesignTimeDbContextFactory<SqlContext>
{
public SqlContext CreateDbContext(string[] args)
{
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false)
.AddUserSecrets<Startup>()
.AddEnvironmentVariables()
.Build();
var builder = new DbContextOptionsBuilder<SqlContext>();
builder.UseSqlServer(config.GetConnectionString("DefaultConnection"));
return new SqlContext(builder.Options);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3417 次 |
| 最近记录: |