I'm having difficulty understanding the Data Protection API.
I'm wanting to set up some net core web applications in a clustered environment (service fabric). Previously what you'd do is just ensure that each machine has the same key in its web.config. Simple. With the new data protection API it seems a little (lottle!) bit more involved.
From the documentation here it appears that it should be as simple as setting up the Data Protection service with the appropriate certificate.
However I tried this:
public static void Main(string[] args)
{
// add data protection services
var serviceCollection = new ServiceCollection();
string thumbPrint = "XXXXXXXXXXXX";
serviceCollection.AddDataProtection()
.ProtectKeysWithDpapiNG($"CERTIFICATE=HashId:{thumbPrint}", flags: Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags.None);
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}");
Console.ReadLine();
}
}
And I just get an exception of
System.InvalidOperationException occurred
HResult=0x80131509
Message=No service for type 'Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository' has been registered.
Which after some digging around turns out that it's because there is no persisted store specified for the keys.
What is advised here? Should I be persisting my keys to some central location (i.e. a share that is available to all my applications). If so, what is the reason why?
You have to supply an implementation of IXmlRepository
which provides the data protection API with a place to store the keys. The ProtectKeysWith*()
directives protect the keys at rest (in basic terms, encrypts the keys before saving them!). Additional info here.
I ended up persisting my keys to AzureStorage. More info here.
serviceCollection.AddDataProtection()
.ProtectKeysWithDpapiNG($"CERTIFICATE=HashId:{thumbPrint}", flags: Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags.None)
.PersistKeysToAzureBlobStorage(/* params */);
It is also worth noting that the certificate used to protect the keys must be stored in a certificate store and the account which the application is running under must have read access. See here.
来源:https://stackoverflow.com/questions/43368226/asp-net-core-data-protection-api-in-a-clustered-environment