Сценарии без поддержки внедрения зависимостей для защиты данных в ASP.NET Core
Автор: Рик Андерсон (Rick Anderson)
Система ASP.NET Core Data Protection обычно добавляется в контейнер службы и используется зависимыми компонентами с помощью внедрения зависимостей (DI). Однако существуют случаи, когда это невозможно или не нужно, особенно при импорте системы в существующее приложение.
Для поддержки этих сценариев пакет Microsoft.AspNetCore.DataProtection.Extensions предоставляет конкретный тип, DataProtectionProviderкоторый предлагает простой способ использования защиты данных без использования di. Тип DataProtectionProvider
реализует IDataProtectionProvider. DataProtectionProvider
Для создания требуется предоставить DirectoryInfo экземпляр, чтобы указать, где должны храниться криптографические ключи поставщика, как показано в следующем примере кода:
using System;
using System.IO;
using Microsoft.AspNetCore.DataProtection;
public class Program
{
public static void Main(string[] args)
{
// Get the path to %LOCALAPPDATA%\myapp-keys
var destFolder = Path.Combine(
System.Environment.GetEnvironmentVariable("LOCALAPPDATA"),
"myapp-keys");
// Instantiate the data protection system at this folder
var dataProtectionProvider = DataProtectionProvider.Create(
new DirectoryInfo(destFolder));
var protector = dataProtectionProvider.CreateProtector("Program.No-DI");
Console.Write("Enter input: ");
var input = Console.ReadLine();
// Protect the payload
var protectedPayload = protector.Protect(input);
Console.WriteLine($"Protect returned: {protectedPayload}");
// Unprotect the payload
var unprotectedPayload = protector.Unprotect(protectedPayload);
Console.WriteLine($"Unprotect returned: {unprotectedPayload}");
Console.WriteLine();
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}
/*
* SAMPLE OUTPUT
*
* Enter input: Hello world!
* Protect returned: CfDJ8FWbAn6...ch3hAPm1NJA
* Unprotect returned: Hello world!
*
* Press any key...
*/
По умолчанию конкретный DataProtectionProvider
тип не шифрует необработанный материал ключа перед сохранением его в файловой системе. Это позволяет поддерживать сценарии, в которых разработчик указывает на сетевую папку, и система защиты данных не может автоматически выводить соответствующий механизм шифрования поrest ключу.
Кроме того, конкретный DataProtectionProvider
тип не изолирует приложения по умолчанию. Все приложения, использующие один и тот же каталог ключей, могут совместно использовать полезные данные до тех пор, пока соответствуют их параметрам назначения.
Конструктор DataProtectionProvider принимает необязательный обратный вызов конфигурации, который можно использовать для настройки поведения системы. В приведенном ниже примере показано восстановление изоляции с явным вызовом SetApplicationName. В примере также показано, как настроить систему для автоматического шифрования сохраненных ключей с помощью Windows DPAPI. Если каталог указывает на общую папку UNC, может потребоваться распространить общий сертификат на всех соответствующих компьютерах и настроить систему для использования шифрования на основе сертификатов с вызовом ProtectKeysWithCertificate.
using System;
using System.IO;
using Microsoft.AspNetCore.DataProtection;
public class Program
{
public static void Main(string[] args)
{
// Get the path to %LOCALAPPDATA%\myapp-keys
var destFolder = Path.Combine(
System.Environment.GetEnvironmentVariable("LOCALAPPDATA"),
"myapp-keys");
// Instantiate the data protection system at this folder
var dataProtectionProvider = DataProtectionProvider.Create(
new DirectoryInfo(destFolder),
configuration =>
{
configuration.SetApplicationName("my app name");
configuration.ProtectKeysWithDpapi();
});
var protector = dataProtectionProvider.CreateProtector("Program.No-DI");
Console.Write("Enter input: ");
var input = Console.ReadLine();
// Protect the payload
var protectedPayload = protector.Protect(input);
Console.WriteLine($"Protect returned: {protectedPayload}");
// Unprotect the payload
var unprotectedPayload = protector.Unprotect(protectedPayload);
Console.WriteLine($"Unprotect returned: {unprotectedPayload}");
Console.WriteLine();
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}
Совет
Экземпляры конкретного DataProtectionProvider
типа являются дорогостоящими для создания. Если приложение поддерживает несколько экземпляров этого типа и если они используют один и тот же каталог хранилища ключей, производительность приложения может снизиться. Если вы используете DataProtectionProvider
тип, рекомендуется создать этот тип один раз и повторно использовать его как можно больше. DataProtectionProvider
Тип и все IDataProtector экземпляры, созданные из него, являются потокобезопасны для нескольких вызывающих.
ASP.NET Core