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

Рик Андерсон (, Даниэль Roth)и Скотт Эдди (By 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 development of an ASP.NET Core app on a development machine. Никогда не храните пароли или другие конфиденциальные данные в исходном коде.Never store passwords or other sensitive data in source code. Производственные секреты не должны использоваться для разработки или тестирования.Production secrets shouldn't be used for development or test. Секреты не должны развертываться вместе с приложением.Secrets shouldn't be deployed with the app. Вместо этого секреты должны быть доступны в рабочей среде с помощью контролируемых средств, таких как переменные среды, Azure Key Vault и т. д. Вы можете хранить и защищать тестовые и рабочие секреты Azure с помощью поставщика конфигурации Azure Key Vault.Instead, secrets should be made available in the production environment through a controlled means like environment variables, Azure Key Vault, etc. 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 automatically replaced by a colon.

Диспетчер секретов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.

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

Диспетчер секретов не шифрует сохраненные секреты и не должен рассматриваться как доверенное хранилище.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

Диспетчер секретов абстрагирует детали реализации, например, где и как хранятся значения.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.

Установка диспетчера секретовInstall the Secret Manager tool

Диспетчер секретов объединяется с .NET Core CLI в пакет SDK для .NET Core 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).

Установите пакет NuGet Microsoft. Extensions. SecretManager. Tools в проекте 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

В средстве "Диспетчер секретов" отображаются примеры использования, параметры и Справка по командам: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.

Примечание

Для запуска средств, определенных в элементах DotNetCliToolReference файла . csproj , необходимо находиться в том же каталоге, что и CSPROJ .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

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

Диспетчер секретов включает команду 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.

Диспетчер секретов можно использовать и в других каталогах.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 открывает файл секреты. JSON в текстовом редакторе.Visual Studio's Manage User Secrets gesture opens a secrets.json file in the text editor. Замените содержимое файла секреты. 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. В следующем примере содержимое входного файла 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 предоставляет доступ к секретам диспетчера секретов.The ASP.NET Core Configuration API provides access to Secret Manager secrets.

Если проект предназначен для .NET Framework, установите пакет NuGet Microsoft. Extensions. Configuration. усерсекретс .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, когда DevelopmentEnvironmentName:CreateDefaultBuilder calls AddUserSecrets when the EnvironmentName is Development:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.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();
}
public Startup(IWebHostEnvironment 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();
}

Установите пакет NuGet Microsoft. Extensions. Configuration. усерсекретс .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)
    {
        app.Run(async (context) =>
        {
            var result = string.IsNullOrEmpty(_moviesApiKey) ? "Null" : "Not Null";
            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)
    {
        app.Run(async (context) =>
        {
            var result = string.IsNullOrEmpty(_moviesApiKey) ? "Null" : "Not Null";
            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"
  }
}

Значение секрета можно задать для свойства Password объекта SqlConnectionStringBuilder, чтобы завершить строку подключения: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

В предыдущем примере двоеточие в именах ключей обозначает иерархию объектов в тайне. 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"

Файл секреты. 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

Все секреты пользователя для приложения удалены из файла секреты. 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