ASP.NET Core 資料保護的非 DI 感知案例
ASP.NET Core 資料保護系統通常會新增至服務容器,並透過相依性插入 (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 執行個體都是多個呼叫端的安全執行緒。