Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In principe bestaat het beveiligen van gegevens uit de volgende stappen:
- Maak een databeschermingscomponent aan van een databeschermingsprovider.
- Roep de
Protectmethode aan met de gegevens die u wilt beveiligen. - Roep de
Unprotectmethode aan met de gegevens die u wilt terugzetten in tekst zonder opmaak.
De meeste frameworks en app-modellen, zoals ASP.NET Core of SignalR, configureren het systeem voor gegevensbeveiliging al en voegen deze toe aan een servicecontainer die toegankelijk is via afhankelijkheidsinjectie. In het volgende voorbeeld ziet u:
- Een servicecontainer configureren voor afhankelijkheidsinjectie en het registreren van de gegevensbeveiligingsstack.
- De provider voor gegevensbescherming ontvangen via DI.
- Een protector maken.
- Gegevens beveiligen en daarna de beveiliging opheffen.
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!
*/
Wanneer u een protector maakt, moet u een of meer doeltekenreeksen opgeven. Een doelstring biedt isolatie tussen consumenten. Een protector die is gemaakt met een doelstring van 'groen' zou bijvoorbeeld geen bescherming van gegevens kunnen opheffen die afkomstig zijn van een protector met het doel 'paars'.
Aanbeveling
Exemplaren van IDataProtectionProvider en IDataProtector zijn thread-safe voor meerdere bellers. Het is bedoeld dat zodra een onderdeel een verwijzing naar een IDataProtector via een aanroep naar CreateProtectorkrijgt, die verwijzing wordt gebruikt voor meerdere aanroepen naar Protect en Unprotect.
Een aanroep naar Unprotect zal CryptographicException veroorzaken als de beveiligde payload niet kan worden geverifieerd of ontcijferd. Sommige onderdelen willen mogelijk fouten negeren tijdens ontsleutelingsoperaties; een onderdeel dat verificatiecookies leest, kan deze fout afhandelen en de aanvraag behandelen alsof deze helemaal geen cookie had, in plaats van de aanvraag volledig te laten mislukken. Onderdelen die dit gedrag willen, moeten specifiek CryptographicException vangen in plaats van alle uitzonderingen in te slikken.
AddOptions gebruiken om aangepaste opslagplaats te configureren
Beschouw de volgende code die een serviceprovider gebruikt omdat de implementatie van IXmlRepository afhankelijk is van een singleton-service:
public void ConfigureServices(IServiceCollection services)
{
// ...
var sp = services.BuildServiceProvider();
services.AddDataProtection()
.AddKeyManagementOptions(o => o.XmlRepository = sp.GetService<IXmlRepository>());
}
Met de voorgaande code wordt de volgende waarschuwing vastgelegd:
Het aanroepen van BuildServiceProvider vanuit toepassingscode resulteert in een extra kopie van singleton-services die worden gemaakt. Overweeg alternatieven zoals het injecteren van services voor afhankelijkheden als parameters voor Configureren.
De volgende code biedt de IXmlRepository implementatie zonder dat u de serviceprovider hoeft te bouwen en daarom extra kopieën van singleton-services hoeft te maken:
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();
}
De voorgaande code verwijdert de aanroep naar GetService en verbergt IConfigureOptions<T>.
De volgende code toont de aangepaste XML-opslagplaats:
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();
}
}
}
De volgende code toont de XmlKey-klasse:
public class XmlKey
{
public Guid Id { get; set; }
public string Xml { get; set; }
public XmlKey()
{
this.Id = Guid.NewGuid();
}
}