Začínáme s rozhraními API ochrany dat v ASP.NET Core
Ochrana dat se v podstatě skládá z následujících kroků:
- Vytvořte ochranu dat od zprostředkovatele ochrany dat.
- Volejte metodu
Protect
s daty, která chcete chránit. - Volejte metodu
Unprotect
s daty, která chcete vrátit zpět do prostého textu.
Většina architektur a modelů aplikací, jako je ASP.NET Core nebo SignalR, už konfiguruje systém ochrany dat a přidá ho do kontejneru služby, ke kterému se přistupuje prostřednictvím injektáže závislostí. Následující ukázka ukazuje:
- Konfigurace kontejneru služby pro injektáž závislostí a registrace zásobníku ochrany dat
- Příjem zprostředkovatele ochrany dat prostřednictvím DI.
- Vytvoření ochrany
- Ochrana a následné zrušení ochrany dat
using System;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static void Main(string[] args)
{
// add data protection services
var serviceCollection = new ServiceCollection();
serviceCollection.AddDataProtection();
var services = serviceCollection.BuildServiceProvider();
// create an instance of MyClass using the service provider
var instance = ActivatorUtilities.CreateInstance<MyClass>(services);
instance.RunSample();
}
public class MyClass
{
IDataProtector _protector;
// the 'provider' parameter is provided by DI
public MyClass(IDataProtectionProvider provider)
{
_protector = provider.CreateProtector("Contoso.MyClass.v1");
}
public void RunSample()
{
Console.Write("Enter input: ");
string input = Console.ReadLine();
// protect the payload
string protectedPayload = _protector.Protect(input);
Console.WriteLine($"Protect returned: {protectedPayload}");
// unprotect the payload
string unprotectedPayload = _protector.Unprotect(protectedPayload);
Console.WriteLine($"Unprotect returned: {unprotectedPayload}");
}
}
}
/*
* SAMPLE OUTPUT
*
* Enter input: Hello world!
* Protect returned: CfDJ8ICcgQwZZhlAlTZT...OdfH66i1PnGmpCR5e441xQ
* Unprotect returned: Hello world!
*/
Při vytváření ochrany musíte zadat jeden nebo více řetězců účelu. Účelový řetězec poskytuje izolaci mezi spotřebiteli. Například ochrana vytvořená s účelovým řetězcem "zelená" by nemohla zrušit ochranu dat poskytovaná ochranou s účelem "fialové".
Tip
IDataProtectionProvider
Instance a IDataProtector
jsou bezpečné pro více volajících. Je zamýšleno, že jakmile komponenta získá odkaz na IDataProtector
prostřednictvím volání CreateProtector
, použije tento odkaz pro více volání a Protect
Unprotect
.
Volání Unprotect
vyvolá kryptografickou výjimkuException, pokud chráněnou datovou část nelze ověřit nebo dešifrovat. Některé komponenty mohou chtít ignorovat chyby během nechráněných operací; Komponenta, která čte soubory cookie pro ověřování, může tuto chybu zpracovat a zacházet s žádostí, jako by vůbec neměla, cookie a ne přímo selhat požadavek. Komponenty, které chtějí toto chování, by měly konkrétně zachytit kryptografickou výjimku místo polykání všech výjimek.
Konfigurace vlastního úložiště pomocí AddOptions
Vezměte v úvahu následující kód, který používá poskytovatele služeb, protože implementace IXmlRepository
má závislost na jednoúčelové službě:
public void ConfigureServices(IServiceCollection services)
{
// ...
var sp = services.BuildServiceProvider();
services.AddDataProtection()
.AddKeyManagementOptions(o => o.XmlRepository = sp.GetService<IXmlRepository>());
}
Předchozí kód zaznamená následující upozornění:
Volání BuildServiceProvider z kódu aplikace vede k vytvoření další kopie jednoúčelových služeb. Zvažte alternativy, jako je například vkládání závislostí, jako jsou parametry konfigurace.
Následující kód poskytuje implementaci IXmlRepository
bez nutnosti sestavovat poskytovatele služeb, a proto vytvářet další kopie singletonových služeb:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataProtectionDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
// Register XmlRepository for data protection.
services.AddOptions<KeyManagementOptions>()
.Configure<IServiceScopeFactory>((options, factory) =>
{
options.XmlRepository = new CustomXmlRepository(factory);
});
services.AddRazorPages();
}
Předchozí kód odebere volání GetService
a skryje IConfigureOptions<T>
.
Následující kód ukazuje vlastní úložiště XML:
using CustomXMLrepo.Data;
using Microsoft.AspNetCore.DataProtection.Repositories;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
public class CustomXmlRepository : IXmlRepository
{
private readonly IServiceScopeFactory factory;
public CustomXmlRepository(IServiceScopeFactory factory)
{
this.factory = factory;
}
public IReadOnlyCollection<XElement> GetAllElements()
{
using (var scope = factory.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<DataProtectionDbContext>();
var keys = context.XmlKeys.ToList()
.Select(x => XElement.Parse(x.Xml))
.ToList();
return keys;
}
}
public void StoreElement(XElement element, string friendlyName)
{
var key = new XmlKey
{
Xml = element.ToString(SaveOptions.DisableFormatting)
};
using (var scope = factory.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<DataProtectionDbContext>();
context.XmlKeys.Add(key);
context.SaveChanges();
}
}
}
Následující kód ukazuje XmlKey třída:
public class XmlKey
{
public Guid Id { get; set; }
public string Xml { get; set; }
public XmlKey()
{
this.Id = Guid.NewGuid();
}
}