ef核心迁移不能使用秘密管理器 [英] ef core migration can't use secret manager

本文介绍了ef核心迁移不能使用秘密管理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我创建 .net 核心 Web 应用程序时,我会在测试期间使用密钥管理器.我通常能够创建一个新的 web 项目(mvc 和 web api),右键单击该项目并选择管理用户机密".这将打开一个 json 文件,我在其中添加秘密.然后我在我的 startup.cs 中使用它,如下所示:

When I create .net 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.

为确保未将其设置为您的生产服务器,我注意到有两种解决方案,此处建议使用一种:https://docs.microsoft.com/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: https://docs.microsoft.com/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核心迁移不能使用秘密管理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆