Поделиться через


Безопасное хранение секретов приложений в разработке в ASP.NET Core

Примечание.

Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 8 этой статьи.

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

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в статье о политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 8 этой статьи.

Внимание

Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

В текущем выпуске см . версию .NET 8 этой статьи.

Авторы: Рик Андерсон (Rick Anderson) и Кирк Ларкин (Kirk Larkin)

Просмотреть или скачать образец кода (описание загрузки)

В этой статье объясняется, как управлять конфиденциальными данными для приложения ASP.NET Core на компьютере разработки. Никогда не хранить пароли или другие конфиденциальные данные в исходном коде или файлах конфигурации. Не следует использовать секреты рабочей среды для разработки или тестирования. Секреты не следует развертывать с приложением. Доступ к рабочим секретам должен осуществляться с помощью контролируемых средств, таких как Azure Key Vault. Тестовые и рабочие секреты Azure могут храниться и защищаться с помощью поставщика конфигурации Azure Key Vault.

Дополнительные сведения о проверке подлинности для развернутых тестовых и рабочих приложений см. в разделе "Безопасные потоки проверки подлинности".

Сведения об использовании секретов пользователей в консольном приложении .NET см . в этой проблеме GitHub.

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

Переменные среды используются для предотвращения хранения секретов приложения в коде или в локальных файлах конфигурации. Переменные среды переопределяют значения конфигурации для всех ранее указанных источников конфигурации.

Рассмотрим веб-приложение ASP.NET Core, в котором включена безопасность отдельных учетных записей пользователей . База данных по умолчанию строка подключения включена в файл проекта appsettings.json с ключомDefaultConnection. По умолчанию строка подключения используется для LocalDB, который выполняется в пользовательском режиме и не требует пароля. Во время развертывания DefaultConnection приложения значение ключа можно переопределить со значением переменной среды. Переменная среды может хранить полный строка подключения с конфиденциальными учетными данными.

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

Переменные среды обычно хранятся в простом незашифрованном тексте. Если компьютер или процесс скомпрометированы, переменные среды могут быть доступны ненадежным сторонам. Могут потребоваться дополнительные меры по предотвращению раскрытия секретов пользователей.

Разделитель : не работает с иерархическими ключами переменных среды на всех платформах. Например, : разделитель не поддерживается Bash. Двойный знак подчеркивания: __

  • Поддерживается всеми платформами.
  • Автоматически заменен двоеточием :.

Диспетчер секретов

Средство Secret Manager хранит конфиденциальные данные во время разработки приложений. В этом контексте конфиденциальные данные — это секрет приложения. Секреты приложений хранятся в отдельном расположении от дерева проекта. Секреты приложения связаны с определенным проектом или совместно используются для нескольких проектов. Секреты приложения не проверяются в системе управления версиями.

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

Средство диспетчера секретов не шифрует сохраненные секреты и не должно рассматриваться как доверенное хранилище. Это только для целей разработки. Ключи и значения хранятся в файле конфигурации JSON в каталоге профилей пользователя.

Как работает средство диспетчера секретов

Средство диспетчера секретов скрывает сведения о реализации, такие как место и способ хранения значений. Средство можно использовать, не зная этих сведений о реализации. Значения хранятся в JSON-файле в папке профиля пользователя локального компьютера:

Путь к файловой системе:

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

В предыдущих путях к файлам замените <user_secrets_id> UserSecretsId значение, указанное в файле проекта.

Не записывайте код, зависящий от расположения или формата данных, сохраненных с помощью средства Диспетчера секретов. Эти сведения о реализации могут измениться. Например, значения секретов не шифруются.

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

Средство Диспетчера секретов работает с параметрами конфигурации для конкретного проекта, хранящимися в профиле пользователя.

Использование CLI

Средство диспетчера секретов init включает команду. Чтобы использовать секреты пользователей, выполните следующую команду в каталоге проекта:

dotnet user-secrets init

Предыдущая команда добавляет UserSecretsId элемент в PropertyGroup файл проекта. По умолчанию внутренний текст UserSecretsId — это GUID. Внутренний текст является произвольным, но является уникальным для проекта.

<PropertyGroup>
  <TargetFramework>netcoreapp3.1</TargetFramework>
  <UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>
</PropertyGroup>

Использование Visual Studio

В Visual Studio щелкните проект правой кнопкой мыши в Обозреватель решений и выберите пункт "Управление секретами пользователей" в контекстном меню. Этот жест добавляет UserSecretsId элемент, заполненный GUID, в файл проекта.

Если GenerateAssemblyInfo имеет значение false

Если создание атрибутов сведений о сборке отключено, добавьте его UserSecretsIdAttribute AssemblyInfo.csвручную. Например:

[assembly: UserSecretsId("your_user_secrets_id")]

При добавлении атрибута UserSecretsId AssemblyInfo.csUserSecretsId вручную значение должно соответствовать значению в файле проекта.

Установка секрета

Определите секрет приложения, состоящий из ключа и его значения. Секрет связан со значением проекта UserSecretsId . Например, выполните следующую команду из каталога, в котором существует файл проекта:

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

В предыдущем примере двоеточие обозначает Movies объектный литерал со свойством ServiceApiKey .

Средство диспетчера секретов также можно использовать из других каталогов. Используйте параметр, чтобы указать путь к файловой системе --project , в котором существует файл проекта. Например:

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

Выравнивание структуры JSON в Visual Studio

Жест "Управление секретами пользователей" Visual Studio открывает secrets.json файл в текстовом редакторе. Замените содержимое secrets.json парами "ключ-значение", которые необходимо сохранить. Например:

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

Структура JSON неструктурирована после изменений через dotnet user-secrets remove или dotnet user-secrets set. Например, выполняется dotnet user-secrets remove "Movies:ConnectionString" свертывание Movies литерала объекта. Измененный файл похож на следующий КОД JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Настройка нескольких секретов

Пакет секретов можно задать, перенастроив JSON в set команду. В следующем примере input.json содержимое файла передаются в set команду.

Откройте командную оболочку и выполните следующую команду:

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

Доступ к секрету

Чтобы получить доступ к секрету, выполните следующие действия:

  1. Регистрация источника конфигурации секретов пользователя
  2. Чтение секрета с помощью API конфигурации

Регистрация источника конфигурации секретов пользователя

Поставщик конфигурации секретов пользователя регистрирует соответствующий источник конфигурации с помощью API конфигурации .NET.

Веб-приложения ASP.NET Core, созданные с помощью dotnet new или Visual Studio, создают следующий код:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

WebApplication.CreateBuilder инициализирует новый экземпляр класса WebApplicationBuilder с предварительно настроенными значениями по умолчанию. Инициализированный WebApplicationBuilder (builder) предоставляет конфигурацию и вызовы AddUserSecrets по умолчанию при EnvironmentName использовании Development:

Чтение секрета с помощью API конфигурации

Рассмотрим следующие примеры чтения Movies:ServiceApiKey ключа:

файл Program.cs:

var builder = WebApplication.CreateBuilder(args);
var movieApiKey = builder.Configuration["Movies:ServiceApiKey"];

var app = builder.Build();

app.MapGet("/", () => movieApiKey);

app.Run();

Razor Модель страниц страниц страницы страницы:

public class IndexModel : PageModel
{
    private readonly IConfiguration _config;

    public IndexModel(IConfiguration config)
    {
        _config = config;
    }

    public void OnGet()
    {
        var moviesApiKey = _config["Movies:ServiceApiKey"];

        // call Movies service with the API key
    }
}

Дополнительные сведения см. в разделе Конфигурация в ASP.NET Core.

Сопоставление секретов с POCO

Сопоставление всего литерала объекта с POCO (простой класс .NET со свойствами) полезно для агрегирования связанных свойств.

Предположим, что файл приложения secrets.json содержит следующие два секрета:

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

Чтобы сопоставить предыдущие секреты с POCO, используйте функцию привязки графа графа конфигурации .NET. Следующий код привязывается к пользовательскому MovieSettings POCO и обращается к значению ServiceApiKey свойства:

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

Movies:ServiceApiKey И Movies:ConnectionString секреты сопоставляются с соответствующими свойствами вMovieSettings:

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

    public string ServiceApiKey { get; set; }
}

Замена строк секретами

Хранение паролей в обычном тексте небезопасно. Например, база данных строка подключения, хранящейся в appsettings.json ней, может содержать пароль для указанного пользователя:

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

Более безопасный подход заключается в хранении пароля в виде секрета. Например:

dotnet user-secrets set "DbPassword" "pass123"

Удалите пару "ключ-значение" Password из строка подключения в appsettings.json. Например:

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

Значение секрета можно задать в свойстве SqlConnectionStringBuilder объектаPassword, чтобы завершить строка подключения:

using System.Data.SqlClient;

var builder = WebApplication.CreateBuilder(args);

var conStrBuilder = new SqlConnectionStringBuilder(
        builder.Configuration.GetConnectionString("Movies"));
conStrBuilder.Password = builder.Configuration["DbPassword"];
var connection = conStrBuilder.ConnectionString;

var app = builder.Build();

app.MapGet("/", () => connection);

app.Run();

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

Предположим, что файл приложения secrets.json содержит следующие два секрета:

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

Выполните следующую команду из каталога, в котором существует файл проекта:

dotnet user-secrets list

Отображаются следующие результаты:

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

В предыдущем примере двоеточие в именах ключей обозначает иерархию объектов внутри secrets.json.

Удаление одного секрета

Предположим, что файл приложения secrets.json содержит следующие два секрета:

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

Выполните следующую команду из каталога, в котором существует файл проекта:

dotnet user-secrets remove "Movies:ConnectionString"

Файл приложения secrets.json был изменен, чтобы удалить пару "ключ-значение", связанную с ключом Movies:ConnectionString :

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

dotnet user-secrets list отображает следующее сообщение:

Movies:ServiceApiKey = 12345

Удаление всех секретов

Предположим, что файл приложения secrets.json содержит следующие два секрета:

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

Выполните следующую команду из каталога, в котором существует файл проекта:

dotnet user-secrets clear

Все секреты пользователей для приложения были удалены из secrets.json файла:

{}

При выполнении dotnet user-secrets list отображается следующее сообщение:

No secrets configured for this application.

Управление секретами пользователей с помощью Visual Studio

Чтобы управлять секретами пользователей в Visual Studio, щелкните проект правой кнопкой мыши в обозревателе решений и выберите пункт "Управление секретами пользователей".

Visual Studio с указанием управления секретами пользователей

Перенос секретов пользователей из ASP платформа .NET Framework в ASP.NET Core

Также см. эту проблему в GitHub.

Секреты пользователей в не веб-приложениях

Проекты, предназначенные Microsoft.NET.Sdk.Web для автоматического включения поддержки секретов пользователей. Для проектов, предназначенных Microsoft.NET.Sdkдля целевых приложений, таких как консольные приложения, установите расширение конфигурации и пакеты NuGet явным образом.

Использование PowerShell:

Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.Configuration.UserSecrets

С использованием .NET CLI:

dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.UserSecrets

После установки пакетов инициализируйте проект и задайте секреты так же, как для веб-приложения. В следующем примере показано консольное приложение, которое извлекает значение секрета, заданного ключом AppSecret:

using Microsoft.Extensions.Configuration;

namespace ConsoleApp;

class Program
{
    static void Main(string[] args)
    {
        IConfigurationRoot config = new ConfigurationBuilder()
            .AddUserSecrets<Program>()
            .Build();

        Console.WriteLine(config["AppSecret"]);
    }
}

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

Рик Андерсон, Кирк Ларкин, Даниэль Рот и Скотт Адди

Просмотреть или скачать образец кода (описание загрузки)

В этой статье объясняется, как управлять конфиденциальными данными для приложения ASP.NET Core на компьютере разработки. Никогда не хранить пароли или другие конфиденциальные данные в исходном коде или файлах конфигурации. Не следует использовать секреты рабочей среды для разработки или тестирования. Секреты не следует развертывать с приложением. Доступ к рабочим секретам должен осуществляться с помощью контролируемых средств, таких как Azure Key Vault. Тестовые и рабочие секреты Azure могут храниться и защищаться с помощью поставщика конфигурации Azure Key Vault.

Дополнительные сведения о проверке подлинности для тестовых и рабочих сред см. в разделе "Безопасные потоки проверки подлинности".

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

Переменные среды используются для предотвращения хранения секретов приложения в коде или в локальных файлах конфигурации. Переменные среды переопределяют значения конфигурации для всех ранее указанных источников конфигурации.

Рассмотрим веб-приложение ASP.NET Core, в котором включена безопасность отдельных учетных записей пользователей . База данных по умолчанию строка подключения включена в файл проекта appsettings.json с ключомDefaultConnection. По умолчанию строка подключения используется для LocalDB, который выполняется в пользовательском режиме и не требует пароля. Во время развертывания DefaultConnection приложения значение ключа можно переопределить со значением переменной среды. Переменная среды может хранить полный строка подключения с конфиденциальными учетными данными.

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

Переменные среды обычно хранятся в простом незашифрованном тексте. Если компьютер или процесс скомпрометированы, переменные среды могут быть доступны ненадежным сторонам. Могут потребоваться дополнительные меры по предотвращению раскрытия секретов пользователей.

Разделитель : не работает с иерархическими ключами переменных среды на всех платформах. Например, : разделитель не поддерживается Bash. Двойный знак подчеркивания: __

  • Поддерживается всеми платформами.
  • Автоматически заменен двоеточием :.

Диспетчер секретов

Средство Secret Manager хранит конфиденциальные данные во время разработки приложений. В этом контексте конфиденциальные данные — это секрет приложения. Секреты приложений хранятся в отдельном расположении от дерева проекта. Секреты приложения связаны с определенным проектом или совместно используются для нескольких проектов. Секреты приложения не проверяются в системе управления версиями.

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

Средство диспетчера секретов не шифрует сохраненные секреты и не должно рассматриваться как доверенное хранилище. Это только для целей разработки. Ключи и значения хранятся в файле конфигурации JSON в каталоге профилей пользователя.

Как работает средство диспетчера секретов

Средство диспетчера секретов скрывает сведения о реализации, такие как место и способ хранения значений. Средство можно использовать, не зная этих сведений о реализации. Значения хранятся в JSON-файле в папке профиля пользователя локального компьютера:

Путь к файловой системе:

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

В предыдущих путях к файлам замените <user_secrets_id> UserSecretsId значение, указанное в файле проекта.

Не записывайте код, зависящий от расположения или формата данных, сохраненных с помощью средства Диспетчера секретов. Эти сведения о реализации могут измениться. Например, секретные значения не шифруются, но могут быть в будущем.

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

Средство Диспетчера секретов работает с параметрами конфигурации для конкретного проекта, хранящимися в профиле пользователя.

Средство диспетчера секретов включает init команду в пакете SDK для .NET Core 3.0.100 или более поздней версии. Чтобы использовать секреты пользователей, выполните следующую команду в каталоге проекта:

dotnet user-secrets init

Предыдущая команда добавляет UserSecretsId элемент в PropertyGroup файл проекта. По умолчанию внутренний текст UserSecretsId — это GUID. Внутренний текст является произвольным, но является уникальным для проекта.

<PropertyGroup>
  <TargetFramework>netcoreapp3.1</TargetFramework>
  <UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>
</PropertyGroup>

В Visual Studio щелкните проект правой кнопкой мыши в Обозреватель решений и выберите пункт "Управление секретами пользователей" в контекстном меню. Этот жест добавляет UserSecretsId элемент, заполненный GUID, в файл проекта.

Установка секрета

Определите секрет приложения, состоящий из ключа и его значения. Секрет связан со значением проекта UserSecretsId . Например, выполните следующую команду из каталога, в котором существует файл проекта:

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

В предыдущем примере двоеточие обозначает Movies объектный литерал со свойством ServiceApiKey .

Средство диспетчера секретов также можно использовать из других каталогов. Используйте параметр, чтобы указать путь к файловой системе --project , в котором существует файл проекта. Например:

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

Выравнивание структуры JSON в Visual Studio

Жест "Управление секретами пользователей" Visual Studio открывает secrets.json файл в текстовом редакторе. Замените содержимое secrets.json парами "ключ-значение", которые необходимо сохранить. Например:

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

Структура JSON неструктурирована после изменений через dotnet user-secrets remove или dotnet user-secrets set. Например, выполняется dotnet user-secrets remove "Movies:ConnectionString" свертывание Movies литерала объекта. Измененный файл похож на следующий КОД JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Настройка нескольких секретов

Пакет секретов можно задать, перенастроив JSON в set команду. В следующем примере input.json содержимое файла передаются в set команду.

Откройте командную оболочку и выполните следующую команду:

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

Доступ к секрету

Чтобы получить доступ к секрету, выполните следующие действия:

  1. Регистрация источника конфигурации секретов пользователя
  2. Чтение секрета с помощью API конфигурации

Регистрация источника конфигурации секретов пользователя

Поставщик конфигурации секретов пользователя регистрирует соответствующий источник конфигурации с помощью API конфигурации .NET.

Источник конфигурации секретов пользователя автоматически добавляется в режиме разработки при вызове CreateDefaultBuilderпроекта. CreateDefaultBuilderвызывается при выполнении EnvironmentName Developmentследующих вызововAddUserSecrets:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Если CreateDefaultBuilder не вызывается, добавьте источник конфигурации секретов пользователя явным образом путем вызова AddUserSecrets ConfigureAppConfiguration. Вызовите AddUserSecrets только в том случае, если приложение выполняется в среде разработки, как показано в следующем примере:

public class Program
{
    public static void Main(string[] args)
    {
        var host = new HostBuilder()
            .ConfigureAppConfiguration((hostContext, builder) =>
            {
                // Add other providers for JSON, etc.

                if (hostContext.HostingEnvironment.IsDevelopment())
                {
                    builder.AddUserSecrets<Program>();
                }
            })
            .Build();
        
        host.Run();
    }
}

Чтение секрета с помощью API конфигурации

Если зарегистрирован источник конфигурации секретов пользователя, API конфигурации .NET может считывать секреты. Внедрение конструктора можно использовать для получения доступа к API конфигурации .NET. Рассмотрим следующие примеры чтения Movies:ServiceApiKey ключа:

Класс запуска:

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}");
        });
    }
}

Razor Модель страниц страниц страницы страницы:

public class IndexModel : PageModel
{
    private readonly IConfiguration _config;

    public IndexModel(IConfiguration config)
    {
        _config = config;
    }

    public void OnGet()
    {
        var moviesApiKey = _config["Movies:ServiceApiKey"];

        // call Movies service with the API key
    }
}

Дополнительные сведения см. в разделе "Конфигурация Access" в разделе "Конфигурация запуска и доступа" на Razor страницах.

Сопоставление секретов с POCO

Сопоставление всего литерала объекта с POCO (простой класс .NET со свойствами) полезно для агрегирования связанных свойств.

Предположим, что файл приложения secrets.json содержит следующие два секрета:

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

Чтобы сопоставить предыдущие секреты с POCO, используйте функцию привязки графа графа конфигурации .NET. Следующий код привязывается к пользовательскому MovieSettings POCO и обращается к значению ServiceApiKey свойства:

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

Movies:ServiceApiKey И Movies:ConnectionString секреты сопоставляются с соответствующими свойствами вMovieSettings:

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

    public string ServiceApiKey { get; set; }
}

Замена строк секретами

Хранение паролей в обычном тексте небезопасно. Например, база данных строка подключения, хранящейся в appsettings.json ней, может содержать пароль для указанного пользователя:

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

Более безопасный подход заключается в хранении пароля в виде секрета. Например:

dotnet user-secrets set "DbPassword" "pass123"

Удалите пару "ключ-значение" Password из строка подключения в appsettings.json. Например:

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

Значение секрета можно задать в свойстве SqlConnectionStringBuilder объектаPassword, чтобы завершить строка подключения:

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;

        // code omitted for brevity
    }

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

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

Предположим, что файл приложения secrets.json содержит следующие два секрета:

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

Выполните следующую команду из каталога, в котором существует файл проекта:

dotnet user-secrets list

Отображаются следующие результаты:

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

В предыдущем примере двоеточие в именах ключей обозначает иерархию объектов внутри secrets.json.

Удаление одного секрета

Предположим, что файл приложения secrets.json содержит следующие два секрета:

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

Выполните следующую команду из каталога, в котором существует файл проекта:

dotnet user-secrets remove "Movies:ConnectionString"

Файл приложения secrets.json был изменен, чтобы удалить пару "ключ-значение", связанную с ключом MoviesConnectionString :

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

dotnet user-secrets list отображает следующее сообщение:

Movies:ServiceApiKey = 12345

Удаление всех секретов

Предположим, что файл приложения secrets.json содержит следующие два секрета:

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

Выполните следующую команду из каталога, в котором существует файл проекта:

dotnet user-secrets clear

Все секреты пользователей для приложения были удалены из secrets.json файла:

{}

При выполнении dotnet user-secrets list отображается следующее сообщение:

No secrets configured for this application.

Управление секретами пользователей с помощью Visual Studio

Чтобы управлять секретами пользователей в Visual Studio, щелкните проект правой кнопкой мыши в обозревателе решений и выберите пункт "Управление секретами пользователей".

Visual Studio с указанием управления секретами пользователей

Перенос секретов пользователей из ASP платформа .NET Framework в ASP.NET Core

Также см. эту проблему в GitHub.

Секреты пользователей в не веб-приложениях

Проекты, предназначенные Microsoft.NET.Sdk.Web для автоматического включения поддержки секретов пользователей. Для проектов, предназначенных Microsoft.NET.Sdkдля целевых приложений, таких как консольные приложения, установите расширение конфигурации и пакеты NuGet явным образом.

Использование PowerShell:

Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.Configuration.UserSecrets

С использованием .NET CLI:

dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.UserSecrets

После установки пакетов инициализируйте проект и задайте секреты так же, как для веб-приложения. В следующем примере показано консольное приложение, которое извлекает значение секрета, заданного ключом AppSecret:

using Microsoft.Extensions.Configuration;

namespace ConsoleApp;

class Program
{
    static void Main(string[] args)
    {
        IConfigurationRoot config = new ConfigurationBuilder()
            .AddUserSecrets<Program>()
            .Build();

        Console.WriteLine(config["AppSecret"]);
    }
}

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