Register IAuthenticationManager with Unity

I use Unity for Dependencies Injection and using Identity Provider to control user login, registration, email confirmation, etc.

When I try to register a user, I have this problem:

The current type, Microsoft.Owin.Security.IAuthenticationManager, is an interface and cannot be constructed. Are you missing the display type?

I do not know how to register this interface (IAuthenticationManager) in a Unity container.

I tried to register an interface with this code, but if I put it, I have another problem:

Not registered IUserTokenProvider.

container.RegisterType<HttpContextBase>( new InjectionFactory(_ => new HttpContextWrapper(HttpContext.Current))); container.RegisterType<IOwinContext>(new InjectionFactory(c => c.Resolve<HttpContextBase>().GetOwinContext())); container.RegisterType<IAuthenticationManager>( new InjectionFactory(c => c.Resolve<IOwinContext>().Authentication)); 

I added the application code (if I do not use Unity, everything works fine):

AccountController

 private IAuthenticationManager AuthenticationManager { get { return HttpContext.GetOwinContext().Authentication; } } 

IdentityConfig.cs

 public class ApplicationUserManager : UserManager<ApplicationUser> { public ApplicationUserManager(IUserStore<ApplicationUser> store) : base(store) { } public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) { var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())); // Configure validation logic for usernames manager.UserValidator = new UserValidator<ApplicationUser>(manager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; // Configure validation logic for passwords manager.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = true, RequireDigit = true, RequireLowercase = true, RequireUppercase = true, }; // Configure user lockout defaults manager.UserLockoutEnabledByDefault = true; manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); manager.MaxFailedAccessAttemptsBeforeLockout = 5; // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user // You can write your own provider and plug in here. manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser> { MessageFormat = "Your security code is: {0}" }); manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser> { Subject = "SecurityCode", BodyFormat = "Your security code is {0}" }); manager.EmailService = new EmailService(); manager.SmsService = new SmsService(); var dataProtectionProvider = options.DataProtectionProvider; if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity")); } return manager; } } // Configure the RoleManager used in the application. RoleManager is defined in the ASP.NET Identity core assembly public class ApplicationRoleManager : RoleManager<IdentityRole> { public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore) : base(roleStore) { } public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context) { return new ApplicationRoleManager(new RoleStore<IdentityRole>(context.Get<ApplicationDbContext>())); } } public class EmailService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { // Plug in your email service here to send an email. return Task.FromResult(0); } } public class SmsService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { // Plug in your sms service here to send a text message. return Task.FromResult(0); } } // This is useful if you do not want to tear down the database each time you run the application. // public class ApplicationDbInitializer : DropCreateDatabaseAlways<ApplicationDbContext> // This example shows you how to create a new database if the Model changes public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext> { protected override void Seed(ApplicationDbContext context) { InitializeIdentityForEF(context); base.Seed(context); } //Create User=Admin@Admin.com with password=Admin@123456 in the Admin role public static void InitializeIdentityForEF(ApplicationDbContext db) { var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>(); const string name = "admin@example.com"; const string password = "Admin@123456"; const string roleName = "Admin"; //Create Role Admin if it does not exist var role = roleManager.FindByName(roleName); if (role == null) { role = new IdentityRole(roleName); var roleresult = roleManager.Create(role); } var user = userManager.FindByName(name); if (user == null) { user = new ApplicationUser { UserName = name, Email = name }; var result = userManager.Create(user, password); result = userManager.SetLockoutEnabled(user.Id, false); } // Add user admin to Role Admin if not already added var rolesForUser = userManager.GetRoles(user.Id); if (!rolesForUser.Contains(role.Name)) { var result = userManager.AddToRole(user.Id, role.Name); } } } public class ApplicationSignInManager : SignInManager<ApplicationUser, string> { public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) : base(userManager, authenticationManager) { } public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user) { return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); } public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context) { return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication); } } 

Thank!!

+48
c # unity-container asp.net-identity
Jul 14 '14 at 7:20
source share
6 answers

Here is what I did to make Unity play well with ASP.NET Identity 2.0:

I added the following to the RegisterTypes method in the UnityConfig class:

 container.RegisterType<DbContext, ApplicationDbContext>( new HierarchicalLifetimeManager()); container.RegisterType<UserManager<ApplicationUser>>( new HierarchicalLifetimeManager()); container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>( new HierarchicalLifetimeManager()); container.RegisterType<AccountController>( new InjectionConstructor()); 
+60
Jul 17 '14 at 14:30
source share

Try adding the line below in the UnityConfig class:

 container.RegisterType<IAuthenticationManager>( new InjectionFactory( o => System.Web.HttpContext.Current.GetOwinContext().Authentication ) ); 
+45
Oct 24 '14 at 10:48
source share

If you really want to use Unity to manage all your dependencies, you can also try registering IAuthenticationManager with Unity

  container.RegisterType<IAuthenticationManager>( new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication)); 

With some minor changes, you can use Unity to resolve all the necessary dependencies for Identity Asp.net.

I found a great post on this (also verified by me) here:

http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/

+4
Sep 21 '15 at 11:51 on
source share

This will also work as a complete configuration allowing you to use Unity with Identity 2.0:

 container.RegisterType<MyDbContext>(new PerRequestLifetimeManager(), new InjectionConstructor()); // Identity container.RegisterType<UserManager<User>>(new HierarchicalLifetimeManager()); container.RegisterType<SignInManager<User, string>>(new HierarchicalLifetimeManager()); container.RegisterType<IUserStore<User>, UserStore<User>>(new PerRequestLifetimeManager(), new InjectionFactory(x => new UserStore<User>(GetConfiguredContainer().Resolve<MyDbContext>()))); container.RegisterType<IAuthenticationManager>(new InjectionFactory(x => HttpContext.Current.GetOwinContext().Authentication)); 

With this parameter, you will not need to register the AccountController or ManageController types with Unity.

+4
May 19 '16 at 1:53
source share

Reputation will not allow me to comment, but to add the marked user3849637s answer for MVC with Update 3 you will also need to add ManageController, as some functions use this with updated forests:

 container.RegisterType<ManageController>(new InjectionConstructor()); 
+2
Jun 08 '15 at 6:09
source share
 container.RegisterFactory<IAuthenticationManager>(o => System.Web.HttpContext.Current.GetOwinContext().Authentication); 

This will answer the question posted by the OP, and will be a relevant answer for anyone who finds it through Google, like me. RegisterFactory is a new way to do this in Unity.

0
Aug 27 '19 at 8:24
source share



All Articles