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

Когда мы разрабатываем какой-либо пет-проект в ASP.NET Core, то особо не задумываемся над тем как мы сохраняем конфиденциальные данные, которые могут нам требоваться при разработке — секретные ключи API, пароли доступа к БД и т.д. Обычно, всё это «богатство» записывается в конфигурацию приложения, например в appsettings.json и используется в разработке. Проблемы начинаются, когда мы отправляем исходный код приложения в какой-нибудь публичный репозиторий или просто выкладываем zip-архив с исходниками на какой-нибудь площадке. В этом случае все наши секреты могут легко перестать быть такими уж секретными. Или второй вариант — несколько разработчиков работают над проектом — у каждого свой набор секретных данных. Как сделать так, чтобы один разработчик не использовал секреты другого? Можно, конечно, обходится старыми способами — постоянно удалять из конфигурации секретные данные и потом передавать исходный код другим, а можно использовать возможности Visual Studio и использовать в проекте управление секретами пользователей.

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

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

Для каждого проекта можно создать своё хранилище секретов. Чтобы инициализировать диспетчер секретов для конкретного проекта можно воспользоваться PowerShell для разработчиков и использовать команду

dotnet user-secrets init

В терминале вы увидите следующее сообщение

для нашего проекта был создан UserSecretsId, который представляет собой обычный GUID уникальный для проекта. Увидеть этот параметр можно в файле проекта. Например, для моего проекта файл AspSecrets.cproj после выполнения команды выглядит следующим образом:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UserSecretsId>1f896247-513b-43dd-ac58-1a01a7536829</UserSecretsId>
  </PropertyGroup>

</Project>

Теперь сохраним какой-нибудь секрет в хранилище. Чтобы добавить новый секрет в хранилище мы должны выполнить команду

dotnet user-secrets set "[ключ]" "[значение]"

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

Эти две команды приведут к тому что в папке: %User%\AppData\Roaming\Microsoft\UserSecrets появится папка с названием соответствующим параметру UserSecretsId в которой будет находится файл secrets.json со следующим содержимым:

{
  "Database:password": "root",
  "Database:login": "user"
}

Чтобы получить все секреты приложения мы также можем воспользоваться командой

dotnet user-secrets list

Чтобы удалить секрет используется команда

dotnet user-secrets remove "[ключ]"

Для удаления всех секретов используется команда

dotnet user-secrets clear

Доступ к секретам из приложения

По умолчанию, для среды окружения «Development» ASP.NET Core уже настраивает необходимые сервисы для работы с секретами пользователей, поэтому, чтение секретов, в этом случае, для нас ничем не отличается от обычной работы с параметрами конфигурации приложения. Например,

public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);

    var login = builder.Configuration["Database:login"];//читаем секрет

    var app = builder.Build();

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

    app.Run();
}

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

namespace AspSecrets
{

    public class DBOptions
    {
        public string Login { get; set; }
        public string Password { get; set; }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            var conf = builder.Configuration.GetSection("Database").Get<DBOptions>();

            var app = builder.Build();

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

            app.Run();
        }
    }
}

здесь мы получаем объект класса DBOptions, содержащий сохраненные ранее секреты пользователя:

var conf = builder.Configuration.GetSection("Database").Get<DBOptions>();

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

Если вам по каким-либо причинам, не удобно использовать консоль для работы с секретами пользователей, то Visual Studio можно вызвать менеджер секретов пользователей в меню проекта:

В этом случае, откроется редактор файла secrets.json

Например, здесь мы можем сделать JSON более читабельным:

{
  "Database": {
    "login": "user",
    "password": "root"
  }
}

Результат чтения секретов пользователя от этого никак не изменится.

Итого

Секреты пользователей позволяют в процессе разработки отделить конфиденциальные данные пользователя от основного кода приложения и избавляет нас от случайных утечек данных. Для управления секретами пользователей мы можем использовать команды dotnet user-secrets или же, воспользоваться диспетчером секретов пользователей Visual Studio. По умолчанию, для среды «Development» в проекте уже настроены необходимые сервисы для получения доступа к секретам пользователей, которые считываются точно также. как и обычные настройки из конфигурации приложения.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии