8

When trying to create a DataProtectionProvider manually I have stumbled upon the Microsoft documenation to DpapiDataProtectionProvider which says:

Used to provide the data protection services that are derived from the Data Protection API. It is the best choice of data protection when you application is not hosted by ASP.NET and all processes are running as the same domain identity.

A question suddenly arises: What is the best choice when your application IS hosted by ASP.NET?

Searching further, it seems the best choice is to obtain the DataProtectionProvider from OWIN. That can be done in Startup configuration, where you have IAppBuilder and using AppBuilderExtensions located in Microsoft.Owin.Security.DataProtection namespace you can call app.GetDataProtectionProvider().

So far, I am quite satisfied. However, now you want to inject the DataProtectionProvider in a constructor of your class (e.g. a UserManager). I have seen one suggestion where you store the DataProtectionProvider in a static property and then use it where you need, but that seems like a rather wrong solution.

I think a solution similar to the following piece of code would be appropriate (using ninject container):

kernel.Bind<IDataProtectionProvider>()
    // beware, method .GetDataProtectionProvider() is fictional
    .ToMethod(c => HttpContext.Current.GetOwinContext().GetDataProtectionProvider())
    .InRequestScope();
Community
  • 1
  • 1
Santhos
  • 3,348
  • 5
  • 30
  • 48

2 Answers2

6

There is a walkthrough that tells you how to register the DataProtectionProvider with Autofac.

builder.Register<IDataProtectionProvider>(c => app.GetDataProtectionProvider()).InstancePerRequest();
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • If I understand this correctly, the DI container should be initialised in the startup class. – Santhos Apr 07 '16 at 11:53
  • Yes, or a class that is called by the `Startup` class, as long as it is part of your composition root. Someone else asked a question about how to setup Ninject with OWIN (I can't seem to find it), and this turns out to be a major rats nest because both OWIN and Ninject want to own the starting point of the application. Considering that Ninject is also one of the slowest DI containers out there, I would personally find a different container that is easier to integrate. – NightOwl888 Apr 07 '16 at 12:07
  • Thanks for the advice, but this is an ongoing project, so changing ninject to something else is an option but for later. – Santhos Apr 07 '16 at 12:09
  • It really seems that the only way to obtain it properly is really using the `IAppBuilder` extension. – Santhos Apr 09 '16 at 05:42
  • The link in this answer is broken. – Hooman Bahreini Jun 18 '20 at 23:27
  • Thanks for letting me know - I have updated the link to the internet archive. – NightOwl888 Jun 19 '20 at 01:26
1

You can also achieve this with Unity with the following line:

container.RegisterType<IDataProtectionProvider>(new InjectionFactory(c => app.GetDataProtectionProvider()));

Where container is

var container = new UnityContainer();

This will allow you to use the DataProtectionProvider in the constructor as follows.

public ApplicationUserManager(IUserStore<ApplicationUser> store, IIdentityMessageService emailService, IDataProtectionProvider dataProtectionProvider)

I prefer this approach over the approach mentioned on this blog post here https://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/, simply because it allows you to have the classes that use the DataProtectionProvider in separate libraries if you would like and it is much cleaner.

Newteq Developer
  • 2,257
  • 1
  • 26
  • 32