Безопасное хранение секретов приложения во время разработки в ASP.NET CoreSafe storage of app secrets in development in ASP.NET Core

По Рик Андерсон, Дэниэл рот, и Scott AddieBy Rick Anderson, Daniel Roth, and Scott Addie

Просмотреть или скачать образец кода (как скачивать)View or download sample code (how to download)

В этом документе описываются методы для хранения и извлечения конфиденциальных данных во время разработки приложения ASP.NET Core.This document explains techniques for storing and retrieving sensitive data during the development of an ASP.NET Core app. Никогда не храните пароли и другие конфиденциальные данные в исходном коде.Never store passwords or other sensitive data in source code. Не следует использовать секреты рабочей среды для разработки или тестирования.Production secrets shouldn't be used for development or test. Для хранения и защиты секретов Azure в ходе тестирования и непосредственной работы используйте Поставщик конфигурации Azure Key Vault.You can store and protect Azure test and production secrets with the Azure Key Vault configuration provider.

Переменные средыEnvironment variables

Переменные среды позволяют избежать хранение секретов приложений в коде или в локальных файлов конфигурации.Environment variables are used to avoid storage of app secrets in code or in local configuration files. Переменные среды переопределить значения конфигурации для всех источников ранее указанной конфигурации.Environment variables override configuration values for all previously specified configuration sources.

Настройки чтения значений переменных среды путем вызова AddEnvironmentVariables в Startup конструктор:Configure the reading of environment variable values by calling AddEnvironmentVariables in the Startup constructor:

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

    if (env.IsDevelopment())
    {
        builder.AddUserSecrets<Startup>();
    }

    Configuration = builder.Build();
}

Рассмотрим веб-приложение ASP.NET Core, в котором учетные записи отдельных пользователей включена безопасность.Consider an ASP.NET Core web app in which Individual User Accounts security is enabled. Строку подключения базы данных по умолчанию включается в проект appsettings.json файл с ключом DefaultConnection.A default database connection string is included in the project's appsettings.json file with the key DefaultConnection. Строка подключения по умолчанию — для LocalDB, который работает в режиме пользователя и пароля не требуется.The default connection string is for LocalDB, which runs in user mode and doesn't require a password. Во время развертывания приложения DefaultConnection значение ключа может быть заменено значение переменной среды.During app deployment, the DefaultConnection key value can be overridden with an environment variable's value. Полная строка подключения с конфиденциальные учетные данные могут хранить в переменной среды.The environment variable may store the complete connection string with sensitive credentials.

Предупреждение

Переменные среды обычно хранятся в обычный и незашифрованное текста.Environment variables are generally stored in plain, unencrypted text. Если компьютер или процесс нарушена, переменные среды может осуществляться с недоверенным сторонам.If the machine or process is compromised, environment variables can be accessed by untrusted parties. Могут потребоваться дополнительные меры, чтобы предотвратить раскрытие секретных данных пользователя.Additional measures to prevent disclosure of user secrets may be required.

При работе с иерархическими ключами в переменных среды разделитель-двоеточие (:) может работать не на всех платформах (например, в Bash).When working with hierarchical keys in environment variables, a colon separator (:) may not work on all platforms (for example, Bash). Двойной знак подчеркивания (__) поддерживается на всех платформах и его можно заменить двоеточием.A double underscore (__) is supported by all platforms and is replaced by a colon.

Менеджер секретовSecret Manager

Средство Secret Manager сохраняет конфиденциальные данные во время разработки проекта ASP.NET Core.The Secret Manager tool stores sensitive data during the development of an ASP.NET Core project. В этом контексте конфиденциальных данных представляет секрет приложения.In this context, a piece of sensitive data is an app secret. Секреты приложения хранятся в отдельном расположении в дереве проекта.App secrets are stored in a separate location from the project tree. Секреты приложения связанные с определенным проектом или совместно используется несколькими проектами.The app secrets are associated with a specific project or shared across several projects. Секреты приложения не проверяются в систему управления версиями.The app secrets aren't checked into source control.

Предупреждение

Средство Secret Manager не шифровать хранимые секреты и не должен рассматриваться в качестве доверенного хранилища.The Secret Manager tool doesn't encrypt the stored secrets and shouldn't be treated as a trusted store. Это только в целях разработки.It's for development purposes only. Ключи и значения хранятся в файле конфигурации JSON в каталоге профиля пользователя.The keys and values are stored in a JSON configuration file in the user profile directory.

Как работает менеджером секретовHow the Secret Manager tool works

Средство Secret Manager абстрагирует детали реализации, например где и как значения сохраняются.The Secret Manager tool abstracts away the implementation details, such as where and how the values are stored. Можно использовать средство, не зная эти детали реализации.You can use the tool without knowing these implementation details. Значения хранятся в файле конфигурации JSON в папке профиля пользователя, система защищена на локальном компьютере:The values are stored in a JSON configuration file in a system-protected user profile folder on the local machine:

Путь файловой системы:File system path:

%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json

В предыдущем пути к файлам, замените <user_secrets_id> с UserSecretsId значение, указанное в .csproj файл.In the preceding file paths, replace <user_secrets_id> with the UserSecretsId value specified in the .csproj file.

Не создавать код, зависящий от расположения или формата данных, сохраненных с помощью диспетчера секретов.Don't write code that depends on the location or format of data saved with the Secret Manager tool. Эти детали реализации могут быть изменены.These implementation details may change. Например его значения не шифруются, но может быть в будущем.For example, the secret values aren't encrypted, but could be in the future.

Установите средство Secret ManagerInstall the Secret Manager tool

Средство Secret Manager связке с .NET Core CLI в .NET Core SDK 2.1.300 или более поздней версии.The Secret Manager tool is bundled with the .NET Core CLI in .NET Core SDK 2.1.300 or later. Для версий пакета SDK для .NET Core до 2.1.300 необходим установки средства.For .NET Core SDK versions before 2.1.300, tool installation is necessary.

Совет

Запустите dotnet --version из командной оболочки, чтобы увидеть установленный номер версии пакета SDK для .NET Core.Run dotnet --version from a command shell to see the installed .NET Core SDK version number.

Если пакет SDK для .NET Core используется включает средство, выводится предупреждение:A warning is displayed if the .NET Core SDK being used includes the tool:

The tool 'Microsoft.Extensions.SecretManager.Tools' is now included in the .NET Core SDK. Information on resolving this warning is available at (https://aka.ms/dotnetclitools-in-box).

Установка Microsoft.Extensions.SecretManager.Tools пакет NuGet в проекте ASP.NET Core.Install the Microsoft.Extensions.SecretManager.Tools NuGet package in your ASP.NET Core project. Пример:For example:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
    <UserSecretsId>1242d6d6-9df3-4031-b031-d9b27d13c25a</UserSecretsId>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore" 
                      Version="1.1.6" />
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" 
                      Version="1.1.2" />
    <PackageReference Include="System.Data.SqlClient" 
                      Version="4.5.0" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" 
                            Version="1.0.1" />
  </ItemGroup>
</Project>

Выполните следующую команду в командной строке для проверки установки средства:Execute the following command in a command shell to validate the tool installation:

dotnet user-secrets -h

Средство Secret Manager отображает пример использования, параметры и команды help:The Secret Manager tool displays sample usage, options, and command help:

Usage: dotnet user-secrets [options] [command]

Options:
  -?|-h|--help                        Show help information
  --version                           Show version information
  -v|--verbose                        Show verbose output
  -p|--project <PROJECT>              Path to project. Defaults to searching the current directory.
  -c|--configuration <CONFIGURATION>  The project configuration to use. Defaults to 'Debug'.
  --id                                The user secret ID to use.

Commands:
  clear   Deletes all the application secrets
  list    Lists all the application secrets
  remove  Removes the specified user secret
  set     Sets the user secret to the specified value

Use "dotnet user-secrets [command] --help" for more information about a command.

Примечание

Должен быть в том же каталоге, что .csproj файл для запуска средства, предназначенные для .csproj файла DotNetCliToolReference элементов.You must be in the same directory as the .csproj file to run tools defined in the .csproj file's DotNetCliToolReference elements.

Включение хранилища секретовEnable secret storage

Средство Secret Manager работает настройки конфигурации конкретного проекта, хранящиеся в профиле пользователя.The Secret Manager tool operates on project-specific configuration settings stored in your user profile.

Включает средство Secret Manager init в пакет SDK для .NET Core 3.0.100 команду или более поздней версии.The Secret Manager tool includes an init command in .NET Core SDK 3.0.100 or later. Чтобы использовать секреты пользователя, выполните следующую команду в каталоге проекта:To use user secrets, run the following command in the project directory:

dotnet user-secrets init

Приведенная выше команда добавляет UserSecretsId сервисном PropertyGroup из .csproj файл.The preceding command adds a UserSecretsId element within a PropertyGroup of the .csproj file. По умолчанию текст внутри UserSecretsId представляет собой идентификатор GUID.By default, the inner text of UserSecretsId is a GUID. Внутренний текст может быть произвольным, но является уникальным для проекта.The inner text is arbitrary, but is unique to the project.

Чтобы использовать секреты пользователя, определить UserSecretsId сервисном PropertyGroup из .csproj файл.To use user secrets, define a UserSecretsId element within a PropertyGroup of the .csproj file. Внутренний текст UserSecretsId может быть произвольным, но является уникальным для проекта.The inner text of UserSecretsId is arbitrary, but is unique to the project. Разработчики обычно создать GUID для UserSecretsId.Developers typically generate a GUID for the UserSecretsId.

<PropertyGroup>
  <TargetFramework>netcoreapp2.1</TargetFramework>
  <UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
  <TargetFramework>netcoreapp1.1</TargetFramework>
  <UserSecretsId>1242d6d6-9df3-4031-b031-d9b27d13c25a</UserSecretsId>
</PropertyGroup>

Совет

В Visual Studio щелкните правой кнопкой мыши проект в обозревателе решений и выберите управление секретами пользователей в контекстном меню.In Visual Studio, right-click the project in Solution Explorer, and select Manage User Secrets from the context menu. Добавляет этот жест UserSecretsId элемент, заполненный идентификатора GUID, что в .csproj файл.This gesture adds a UserSecretsId element, populated with a GUID, to the .csproj file.

Значение секретаSet a secret

Определите секрет приложения, состоящие из ключа и его значение.Define an app secret consisting of a key and its value. Секрет связан с проектом UserSecretsId значение.The secret is associated with the project's UserSecretsId value. Например, выполните следующую команду из каталога, в котором .csproj файл существует:For example, run the following command from the directory in which the .csproj file exists:

dotnet user-secrets set "Movies:ServiceApiKey" "12345"

В приведенном выше примере двоеточия обозначает, что Movies — это объект литерал с ServiceApiKey свойство.In the preceding example, the colon denotes that Movies is an object literal with a ServiceApiKey property.

Средство Secret Manager можно использовать из других каталогов.The Secret Manager tool can be used from other directories too. Используйте --project параметр, чтобы указать путь в файловой системе, по которому .csproj файл существует.Use the --project option to supply the file system path at which the .csproj file exists. Пример:For example:

dotnet user-secrets set "Movies:ServiceApiKey" "12345" --project "C:\apps\WebApp1\src\WebApp1"

Структура JSON, сведение в Visual StudioJSON structure flattening in Visual Studio

Visual Studio управление секретами пользователей жестов откроется secrets.json файл в текстовом редакторе.Visual Studio's Manage User Secrets gesture opens a secrets.json file in the text editor. Замените содержимое файла secrets.json с парами "ключ значение" для сохранения.Replace the contents of secrets.json with the key-value pairs to be stored. Пример:For example:

{
  "Movies": {
    "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
    "ServiceApiKey": "12345"
  }
}

Структура JSON выравнивается после внесения изменений с помощью dotnet user-secrets remove или dotnet user-secrets set.The JSON structure is flattened after modifications via dotnet user-secrets remove or dotnet user-secrets set. Например, на котором работают dotnet user-secrets remove "Movies:ConnectionString" сворачивает Movies литерала объекта.For example, running dotnet user-secrets remove "Movies:ConnectionString" collapses the Movies object literal. Измененный файл будет выглядеть примерно так:The modified file resembles the following:

{
  "Movies:ServiceApiKey": "12345"
}

Задайте несколько секретных кодовSet multiple secrets

Пакет секреты можно задать путем передачи JSON для set команды.A batch of secrets can be set by piping JSON to the set command. В следующем примере input.json содержимое файла передаются по конвейеру в set команды.In the following example, the input.json file's contents are piped to the set command.

Откройте командную оболочку и выполните следующую команду:Open a command shell, and execute the following command:

type .\input.json | dotnet user-secrets set

Доступ к секретаAccess a secret

API конфигурации ASP.NET Core предоставляет доступ к Secret Manager секреты.The ASP.NET Core Configuration API provides access to Secret Manager secrets.

Если проект нацелен на .NET Framework, установить Microsoft.Extensions.Configuration.UserSecrets пакет NuGet.If your project targets .NET Framework, install the Microsoft.Extensions.Configuration.UserSecrets NuGet package.

В ASP.NET Core 2.0 или более поздней версии, источник конфигурации секреты пользователя автоматически добавляется в режиме разработки, пока проект не вызывает CreateDefaultBuilder для инициализации нового экземпляра узла с помощью предварительно настроенных значений по умолчанию.In ASP.NET Core 2.0 or later, the user secrets configuration source is automatically added in development mode when the project calls CreateDefaultBuilder to initialize a new instance of the host with preconfigured defaults. CreateDefaultBuilder вызовы AddUserSecrets при EnvironmentNameDevelopment:CreateDefaultBuilder calls AddUserSecrets when the EnvironmentName is Development:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();

Когда CreateDefaultBuilder не вызывается, добавить источник конфигурации секреты пользователя явно, вызвав AddUserSecrets в Startup конструктор.When CreateDefaultBuilder isn't called, add the user secrets configuration source explicitly by calling AddUserSecrets in the Startup constructor. Вызовите AddUserSecrets только когда приложение выполняется в среде разработки, как показано в следующем примере:Call AddUserSecrets only when the app runs in the Development environment, as shown in the following example:

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

    if (env.IsDevelopment())
    {
        builder.AddUserSecrets<Startup>();
    }

    Configuration = builder.Build();
}

Установка Microsoft.Extensions.Configuration.UserSecrets пакет NuGet.Install the Microsoft.Extensions.Configuration.UserSecrets NuGet package.

Добавить источник конфигурации секреты пользователя с помощью вызова AddUserSecrets в Startup конструктор:Add the user secrets configuration source with a call to AddUserSecrets in the Startup constructor:

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

    if (env.IsDevelopment())
    {
        builder.AddUserSecrets<Startup>();
    }

    Configuration = builder.Build();
}

Секреты пользователя можно получить через Configuration API:User secrets can be retrieved via the Configuration API:

public class Startup
{
    private string _moviesApiKey = null;

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        _moviesApiKey = Configuration["Movies:ServiceApiKey"];
    }

    public void Configure(IApplicationBuilder app)
    {
        var result = string.IsNullOrEmpty(_moviesApiKey) ? "Null" : "Not Null";
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync($"Secret is {result}");
        });
    }
}
public class Startup
{
    private string _moviesApiKey = null;
    
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", 
                         optional: false, 
                         reloadOnChange: true)
            .AddEnvironmentVariables();

        if (env.IsDevelopment())
        {
            builder.AddUserSecrets<Startup>();
        }

        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        _moviesApiKey = Configuration["Movies:ServiceApiKey"];
    }

    public void Configure(IApplicationBuilder app)
    {
        var result = string.IsNullOrEmpty(_moviesApiKey) ? "Null" : "Not Null";
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync($"Secret is {result}");
        });
    }
}

Сопоставить секреты POCOMap secrets to a POCO

Сопоставление всей литерала объекта POCO (простой класс .NET со свойствами) полезен для объединения связанных свойств.Mapping an entire object literal to a POCO (a simple .NET class with properties) is useful for aggregating related properties.

Предположим, приложение secrets.json файл содержит следующие два секрета:Assume the app's secrets.json file contains the following two secrets:

{
  "Movies": {
    "ServiceApiKey": "12345",
    "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Чтобы сопоставить выше секреты POCO, используйте Configuration API привязке графа объектов функции.To map the preceding secrets to a POCO, use the Configuration API's object graph binding feature. Следующий код привязывается к пользовательской MovieSettings POCO и обращается к ServiceApiKey значение свойства:The following code binds to a custom MovieSettings POCO and accesses the ServiceApiKey property value:

var moviesConfig = Configuration.GetSection("Movies")
                                .Get<MovieSettings>();
_moviesApiKey = moviesConfig.ServiceApiKey;
var moviesConfig = new MovieSettings();
Configuration.GetSection("Movies").Bind(moviesConfig);
_moviesApiKey = moviesConfig.ServiceApiKey;

Movies:ConnectionString И Movies:ServiceApiKey секреты, сопоставляются с соответствующих свойств в MovieSettings:The Movies:ConnectionString and Movies:ServiceApiKey secrets are mapped to the respective properties in MovieSettings:

public class MovieSettings
{
    public string ConnectionString { get; set; }

    public string ServiceApiKey { get; set; }
}

Строка замены с секретамиString replacement with secrets

Хранить пароли в виде обычного текста небезопасно.Storing passwords in plain text is insecure. Например, строку подключения базы данных хранятся в appsettings.json может быть указан пароль для указанного пользователя:For example, a database connection string stored in appsettings.json may include a password for the specified user:

{
  "ConnectionStrings": {
    "Movies": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;User Id=johndoe;Password=pass123;MultipleActiveResultSets=true"
  }
}

Более безопасный подход — в том, чтобы сохранить пароль в качестве секрета.A more secure approach is to store the password as a secret. Пример:For example:

dotnet user-secrets set "DbPassword" "pass123"

Удалить Password пару ключ значение из строки подключения в appsettings.json.Remove the Password key-value pair from the connection string in appsettings.json. Пример:For example:

{
  "ConnectionStrings": {
    "Movies": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;User Id=johndoe;MultipleActiveResultSets=true"
  }
}

Можно задать значение секрета SqlConnectionStringBuilder объекта Password свойство, чтобы завершить строку подключения:The secret's value can be set on a SqlConnectionStringBuilder object's Password property to complete the connection string:

public class Startup
{
    private string _connection = null;

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        var builder = new SqlConnectionStringBuilder(
            Configuration.GetConnectionString("Movies"));
        builder.Password = Configuration["DbPassword"];
        _connection = builder.ConnectionString;
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync($"DB Connection: {_connection}");
        });
    }
}
public class Startup
{
    private string _connection = null;
    
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json",
                         optional: false,
                         reloadOnChange: true)
            .AddEnvironmentVariables();

        if (env.IsDevelopment())
        {
            builder.AddUserSecrets<Startup>();
        }

        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        var builder = new SqlConnectionStringBuilder(
            Configuration.GetConnectionString("Movies"));
        builder.Password = Configuration["DbPassword"];
        _connection = builder.ConnectionString;
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync($"DB Connection: {_connection}");
        });
    }
}

Вывод списка секретовList the secrets

Предположим, приложение secrets.json файл содержит следующие два секрета:Assume the app's secrets.json file contains the following two secrets:

{
  "Movies": {
    "ServiceApiKey": "12345",
    "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Выполните следующую команду из каталога, в котором .csproj файл существует:Run the following command from the directory in which the .csproj file exists:

dotnet user-secrets list

Появится следующий результат:The following output appears:

Movies:ConnectionString = Server=(localdb)\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true
Movies:ServiceApiKey = 12345

В приведенном выше примере двоеточия в имена ключей означает иерархии объектов в пределах secrets.json.In the preceding example, a colon in the key names denotes the object hierarchy within secrets.json.

Удалить секрет единогоRemove a single secret

Предположим, приложение secrets.json файл содержит следующие два секрета:Assume the app's secrets.json file contains the following two secrets:

{
  "Movies": {
    "ServiceApiKey": "12345",
    "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Выполните следующую команду из каталога, в котором .csproj файл существует:Run the following command from the directory in which the .csproj file exists:

dotnet user-secrets remove "Movies:ConnectionString"

Приложения secrets.json файл был изменен, чтобы удалить пару ключ значение, связанных с MoviesConnectionString ключ:The app's secrets.json file was modified to remove the key-value pair associated with the MoviesConnectionString key:

{
  "Movies": {
    "ServiceApiKey": "12345"
  }
}

Под управлением dotnet user-secrets list отображается следующее сообщение:Running dotnet user-secrets list displays the following message:

Movies:ServiceApiKey = 12345

Удалить все секретыRemove all secrets

Предположим, приложение secrets.json файл содержит следующие два секрета:Assume the app's secrets.json file contains the following two secrets:

{
  "Movies": {
    "ServiceApiKey": "12345",
    "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Выполните следующую команду из каталога, в котором .csproj файл существует:Run the following command from the directory in which the .csproj file exists:

dotnet user-secrets clear

Все секреты пользователя приложения будут удалены из secrets.json файла:All user secrets for the app have been deleted from the secrets.json file:

{}

Под управлением dotnet user-secrets list отображается следующее сообщение:Running dotnet user-secrets list displays the following message:

No secrets configured for this application.

Дополнительные ресурсыAdditional resources