Scénáře ochrany dat v ASP.NET Core nevyužívající injektáž závislostí

Autor: Rick Anderson

Systém ASP.NET Core Data Protection se obvykle přidává do kontejneru služby a využívá závislé komponenty prostřednictvím injektáže závislostí (DI). Existují však případy, kdy to není možné nebo žádoucí, zejména při importu systému do existující aplikace.

Pro podporu těchto scénářů poskytuje balíček Microsoft.AspNetCore.DataProtection.Extensions konkrétní typ, DataProtectionProviderkterý nabízí jednoduchý způsob použití ochrany dat bez nutnosti spoléhat se na DI. Typ DataProtectionProvider implementuje IDataProtectionProvider. DataProtectionProvider Vytváření vyžaduje pouze poskytnutí DirectoryInfo instance, která indikuje, kde by se kryptografické klíče zprostředkovatele měly ukládat, jak je vidět v následující ukázce kódu:

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...
*/

Ve výchozím nastavení DataProtectionProvider konkrétní typ nešifruje materiál nezpracovaného klíče před uložením do systému souborů. Jde o podporu scénářů, kdy vývojář odkazuje na sdílenou síťovou složku a systém Ochrany dat nemůže automaticky odvodit vhodný šifrovací mechanismus klíče neaktivního stavu.

Konkrétní typ navíc DataProtectionProvider ve výchozím nastavení neizoluje aplikace . Všechny aplikace používající stejný adresář klíčů můžou sdílet datové části, pokud se shodují jejich účelové parametry .

Konstruktor DataProtectionProvider přijímá volitelné zpětné volání konfigurace, které lze použít k úpravě chování systému. Následující ukázka ukazuje obnovení izolace explicitním voláním SetApplicationName. Ukázka také ukazuje konfiguraci systému tak, aby automaticky šifroval trvalé klíče pomocí Rozhraní WINDOWS DPAPI. Pokud adresář odkazuje na sdílenou složku UNC, můžete chtít distribuovat sdílený certifikát mezi všechny relevantní počítače a nakonfigurovat systém tak, aby používal šifrování založené na certifikátech s voláním 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();
    }
}

Tip

Vytvoření instancí konkrétního DataProtectionProvider typu je nákladné. Pokud aplikace udržuje více instancí tohoto typu a pokud všechny používají stejný adresář úložiště klíčů, může výkon aplikace snížit. Pokud použijete DataProtectionProvider typ, doporučujeme tento typ vytvořit jednou a co nejvíce ho znovu použít. Typ DataProtectionProvider a všechny IDataProtector instance vytvořené z něj jsou pro více volajících bezpečné pro více volajících.